shithub: scc

Download patch

ref: 92778381c37454ad7857d0e7ee6608920544d7d2
parent: 5c0bbb5ff6603cf20c4e3f4ec16dd7b60799cb85
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jun 14 14:50:17 EDT 2022

cc1: Improve error handling in field()

There were cases where a symbol without type could be
returned and there was a possibility of modyfing  the
type of an already declared symbol.

--- a/src/cmd/cc/cc1/decl.c
+++ b/src/cmd/cc/cc1/decl.c
@@ -865,7 +865,6 @@
 	char *name = (sym->name) ? sym->name : anon;
 	Type *structp = dcl->parent, *tp = dcl->type;
 	TINT n = structp->n.elem;
-	int err = 0;
 
 	if (accept(':')) {
 		Node *np;
@@ -890,28 +889,30 @@
 		return sym;
 	}
 
+	if (sym->flags & SDECLARED) {
+		errorp("duplicated member '%s'", name);
+		return sym;
+	}
+
+	if ((tp->prop & TDEFINED) == 0) {
+		errorp("field '%s' has incomplete type", name);
+		tp = inttype;
+	}
 	if (tp->op == FTN) {
 		errorp("invalid type '%s' in struct/union", name);
-		err = 1;
+		tp = inttype;
 	}
-	if (dcl->sclass) {
+	if (dcl->sclass)
 		errorp("storage class in struct/union field '%s'", name);
-		err = 1;
-	}
-	if (!(tp->prop & TDEFINED)) {
-		error("field '%s' has incomplete type", name);
-		err = 1;
-	}
-	if (err)
-		return sym;
 
-	if (sym->flags & SDECLARED)
-		error("duplicated member '%s'", name);
-	sym->flags |= SFIELD|SDECLARED;
 	sym->type = tp;
+	sym->flags |= SFIELD|SDECLARED;
 
-	if (n == NR_FIELDS)
-		error("too many fields in struct/union");
+	if (n == NR_FIELDS) {
+		errorp("too many fields in struct/union");
+		return sym;
+	}
+
 	DBG("New field '%s' in namespace %d\n", name, structp->ns);
 	structp->p.fields = xrealloc(structp->p.fields, ++n * sizeof(*sym));
 	structp->p.fields[n-1] = sym;