scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mdecl.c | 17+++++++++++++----
Msymbol.h | 5++++-
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;