aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--lib.c2
-rw-r--r--lib.h1
-rw-r--r--sparse.c33
-rw-r--r--validation/compound-sizes.c88
4 files changed, 124 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index b94ed847..24d19cd7 100644
--- a/lib.c
+++ b/lib.c
@@ -259,6 +259,7 @@ int dump_macro_defs = 0;
int dbg_entry = 0;
int dbg_dead = 0;
+int dbg_compound = 0;
unsigned long fdump_ir;
int fmem_report = 0;
@@ -719,6 +720,7 @@ static char **handle_switch_W(char *arg, char **next)
static struct flag debugs[] = {
{ "entry", &dbg_entry},
{ "dead", &dbg_dead},
+ { "compound", &dbg_compound},
};
diff --git a/lib.h b/lib.h
index e34bb9a0..aea46741 100644
--- a/lib.h
+++ b/lib.h
@@ -168,6 +168,7 @@ extern int dump_macro_defs;
extern int dbg_entry;
extern int dbg_dead;
+extern int dbg_compound;
extern unsigned int fmax_warnings;
extern int fmem_report;
diff --git a/sparse.c b/sparse.c
index ef5ee476..768b9125 100644
--- a/sparse.c
+++ b/sparse.c
@@ -272,6 +272,37 @@ static void check_context(struct entrypoint *ep)
check_bb_context(ep, ep->entry->bb, in_context, out_context);
}
+/* list_compound_symbol - symbol info for arrays, structures, unions */
+static void list_compound_symbol(struct symbol *sym)
+{
+ struct symbol *base;
+
+ /* Only show symbols that have a positive size */
+ if (sym->bit_size <= 0)
+ return;
+ if (!sym->ctype.base_type)
+ return;
+ /* Don't show unnamed types */
+ if (!sym->ident)
+ return;
+
+ if (sym->type == SYM_NODE)
+ base = sym->ctype.base_type;
+ else
+ base = sym;
+ switch (base->type) {
+ case SYM_STRUCT: case SYM_UNION: case SYM_ARRAY:
+ break;
+ default:
+ return;
+ }
+
+ info(sym->pos, "%s: compound size %u, alignment %lu",
+ show_typename(sym),
+ bits_to_bytes(sym->bit_size),
+ sym->ctype.alignment);
+}
+
static void check_symbols(struct symbol_list *list)
{
struct symbol *sym;
@@ -287,6 +318,8 @@ static void check_symbols(struct symbol_list *list)
check_context(ep);
}
+ if (dbg_compound)
+ list_compound_symbol(sym);
} END_FOR_EACH_PTR(sym);
if (Wsparse_error && die_if_error)
diff --git a/validation/compound-sizes.c b/validation/compound-sizes.c
new file mode 100644
index 00000000..d8ccf605
--- /dev/null
+++ b/validation/compound-sizes.c
@@ -0,0 +1,88 @@
+// This tests sparse "-vcompound" output.
+#define NULL ((void*)0)
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+// Do not list functions.
+static int do_nothing(void)
+{}
+
+// no:
+static inline int zero(void)
+{
+ return 0 / 1;
+}
+
+// no:
+struct inventory {
+ unsigned char description[64];
+ unsigned char department[64];
+ uint32_t dept_number;
+ uint32_t item_cost;
+ uint64_t stock_number;
+ uint32_t tally[12]; // per month
+};
+
+// no
+static struct inventory *get_inv(uint64_t stocknum)
+{
+ return NULL;
+}
+
+// no
+union un {
+ struct inventory inv;
+ unsigned char bytes[0];
+};
+
+// yes
+static union un un;
+
+// yes
+static struct inventory inven[100];
+
+// no
+typedef struct inventory inventory_t;
+
+// no
+static struct inventory *invptr;
+
+// yes
+static inventory_t invent[10];
+
+// no
+static float floater;
+static double double_float;
+
+// yes
+static float floats[42];
+static double doubles[84];
+
+// no
+int main(void)
+{
+ // no, these are not global.
+ struct inventory inv[10];
+ inventory_t invt[10];
+ // what about statics?
+ static struct inventory invtop;
+ static inventory_t inv_top;
+ static uint64_t stocknums[100];
+
+ invptr = get_inv(42000);
+ return 0;
+}
+
+/*
+ * check-name: compound-sizes
+ * check-command: sparse -vcompound $file
+ * check-assert: _Alignof(long long) == 8
+ *
+ * check-error-start
+compound-sizes.c:39:17: union un static [toplevel] un: compound size 192, alignment 8
+compound-sizes.c:42:25: struct inventory static [toplevel] inven[100]: compound size 19200, alignment 8
+compound-sizes.c:51:33: struct inventory static [toplevel] [usertype] invent[10]: compound size 1920, alignment 8
+compound-sizes.c:58:25: float static [toplevel] floats[42]: compound size 168, alignment 4
+compound-sizes.c:59:25: double static [toplevel] doubles[84]: compound size 672, alignment 8
+ * check-error-end
+ */