shithub: scc

Download patch

ref: ef6b767b7d3ea2088f8652fe5ea76117661edef0
parent: cbdbbf1076c80ffe2281b687d6539905c485c49b
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Jan 9 16:30:52 EST 2016

Detect redefinition of external symbols.

An external declaration is a tentative definition, and a file can contain
several tentative definition for a symbol, but when an external
declaration also has an initializer, it is a definition. Due to the order
in the if this error was not catched.

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -1247,10 +1247,13 @@
 
 	np = assignop(OINIT, varnode(sym), np);
 
-	if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {
+	if (flags & ISDEFINED) {
+		errorp("redeclaration of '%s'", sym->name);
+	} else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {
 		if (!np->right->constant)
 			errorp("initializer element is not constant");
 		emit(OINIT, np);
+		sym->flags |= ISDEFINED;
 	} else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
 		errorp("'%s' has both '%s' and initializer",
 		       sym->name, (flags&ISEXTERN) ? "extern" : "typedef");