commit da40be16dc3adcabf313f467b6ac91bca512038b
parent 80e7f658d5789313b32f2fb7677032766aca5c42
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 24 Sep 2013 22:01:10 +0200
Detect unnamed structs
When a struct is declared without tag it is a unnamed struct. If
it is not declared a variable at the same time the struct is defined
is not posible use this struct, because it is not posible declare
a variable of this type.
Diffstat:
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/decl.c b/decl.c
@@ -85,15 +85,20 @@ dirdcl(register struct ctype *tp, unsigned char ns)
static void
new_struct(register struct ctype *tp)
{
+ struct symbol *sym = NULL;
+
if (yytoken == IDEN) {
- (namespace(NS_STRUCT, -1)->ctype = tp)->refcnt++;
+ sym = namespace(NS_STRUCT, -1);
+ (sym->ctype = tp)->refcnt++;
next();
}
if (nr_structs == NR_MAXSTRUCTS)
error("too much structs/unions/enum defined");
if (structp == &structbuf[NR_STRUCT_LEVEL])
error("too much nested structs/unions");
- tp->c_struct = *structp++ = nr_structs;
+ tp->ns = *structp++ = nr_structs;
+ tp->forward = 1;
+ tp->sym = sym;
}
static struct ctype * spec(void);
@@ -114,7 +119,7 @@ struct_dcl(unsigned char ns)
error("storage specifier in a struct/union field declaration");
}
- do { /* TODO: detect unnamed structs */
+ do {
declarator(base, ns);
tp = decl_type(base);
(cursym->ctype = tp)->refcnt++;
@@ -135,7 +140,7 @@ struct_spec(register struct ctype *tp)
error("struct/union already defined");
do
- struct_dcl(tp->c_struct);
+ struct_dcl(tp->ns);
while (!accept('}'));
tp->forward = 0;
@@ -337,6 +342,10 @@ repeat: if (!(tp = spec())) {
warn(options.useless,
"useless storage class specifier in empty declaration");
}
+ if (!tp->sym && type != ENUM) {
+ warn(options.useless,
+ "unnamed struct/union that defines no instances");
+ }
} else {
warn(options.useless,
"useless type name in empty declaration");
diff --git a/symbol.h b/symbol.h
@@ -35,7 +35,10 @@ struct ctype {
bool forward : 1;
union {
unsigned len;
- unsigned char c_struct;
+ struct {
+ struct symbol *sym;
+ unsigned char ns;
+ };
};
struct ctype *base;
unsigned char refcnt;