shithub: scc

Download patch

ref: da40be16dc3adcabf313f467b6ac91bca512038b
parent: 80e7f658d5789313b32f2fb7677032766aca5c42
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 24 18:01:10 EDT 2013

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.

--- a/decl.c
+++ b/decl.c
@@ -85,8 +85,11 @@
 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)
@@ -93,7 +96,9 @@
 		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 @@
 		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 @@
 		error("struct/union already defined");
 
 	do
-		struct_dcl(tp->c_struct);
+		struct_dcl(tp->ns);
 	while (!accept('}'));
 	tp->forward = 0;
 
@@ -336,6 +341,10 @@
 			    tp->c_register || tp->c_const || tp->c_volatile) {
 				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,
--- a/symbol.h
+++ b/symbol.h
@@ -35,7 +35,10 @@
 	bool forward : 1;
 	union {
 		unsigned len;
-		unsigned char c_struct;
+		struct {
+			struct symbol *sym;
+			unsigned char ns;
+		};
 	};
 	struct ctype *base;
 	unsigned char refcnt;