shithub: scc

Download patch

ref: 8182a159c71c03a6cd28b9c8651c26db5e1743c4
parent: 6650268eca2441b777636a3aad411b2d70e23281
parent: 605c7cdb0678c691f3c118154501f8ec2e8f852c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Aug 21 09:08:20 EDT 2015

Merge remote-tracking branch 'origin/master'

Conflicts:
	cc1/symbol.c

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -300,7 +300,7 @@
 extern void error(char *fmt, ...);
 extern void warn(char *fmt, ...);
 extern void unexpected(void);
-extern void printerr(char *fmt, ...);
+extern void errorp(char *fmt, ...);
 extern void cpperror(char *fmt, ...);
 
 /* types.c */
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -628,7 +628,7 @@
 	popctx();               /* the symbols freed at the  end        */
 
 	if (yytoken != EOFTOK && !cppoff)
-		printerr("trailing characters after preprocessor directive");
+		errorp("trailing characters after preprocessor directive");
 	disexpand = 0;
 	lexmode = CCMODE;
 
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -128,7 +128,8 @@
 	case STATIC:
 	case EXTERN:
 	case AUTO:
-		error("bad storage class in function parameter");
+		errorp("bad storage class in function parameter");
+		break;
 	case REGISTER:
 		sym->flags |= ISREGISTER;
 		break;
@@ -271,7 +272,7 @@
 			break;
 		case TQUALIFIER:
 			if (qlf && qlf != RESTRICT)
-				goto invalid_type;
+				errorp("invalid type specification");
 			qlf |= yylval.token;
 			next();
 			continue;
@@ -319,11 +320,11 @@
 			goto return_type;
 		}
 		if (*p)
-			goto invalid_type;
+			errorp("invalid type specification");
 		*p = yylval.token;
 		if (dcl) {
 			if (size || sign)
-				goto invalid_type;
+				errorp("invalid type specification");
 			tp = (*dcl)();
 			goto return_type;
 		} else {
@@ -346,9 +347,6 @@
 		}
 	}
 	return tp;
-
-invalid_type:
-	error("invalid type specification");
 }
 
 /* TODO: check correctness of the initializator  */
@@ -528,6 +526,14 @@
 	return sym;
 }
 
+static void
+bad_storage(Type *tp, char *name)
+{
+	if (tp->op != FTN)
+		errorp("incorrect storage class for file-scope declaration");
+	errorp("invalid storage class for function '%s'", name);
+}
+
 static Symbol *
 identifier(struct decl *dcl)
 {
@@ -571,7 +577,6 @@
 
 	if (sym == NULL) {
 		sym = dcl->sym;
-		flags = sym->flags;
 		if (!eqtype(sym->type, tp))
 			error("conflicting types for '%s'", name);
 		if (sym->token == TYPEIDEN && sclass != TYPEDEF ||
@@ -582,32 +587,49 @@
 			if (!(sym->flags & ISEXTERN) || sclass != EXTERN)
 				goto redeclaration;
 		} else {
+			sym->u.pars = dcl->pars;
+			flags = sym->flags;
+
 			switch (sclass) {
 			case REGISTER:
 			case AUTO:
-				goto bad_storage;
+				bad_storage(tp, name);
+				break;
 			case NOSCLASS:
-				if (flags & ISPRIVATE)
-					goto non_after_static;
-				flags &= ~ISEXTERN;
-				flags |= ISGLOBAL;
+				if ((flags & ISPRIVATE) == 0) {
+					flags &= ~ISEXTERN;
+					flags |= ISGLOBAL;
+					break;
+				}
+				errorp("non-static declaration of '%s' follows static declaration",
+				       name);
+				break;
 			case TYPEDEF:
 			case EXTERN:
 				break;
 			case STATIC:
-				if (flags & (ISGLOBAL|ISEXTERN))
-					goto static_after_non;
-				flags |= ISPRIVATE;
+				if ((flags & (ISGLOBAL|ISEXTERN)) == 0) {
+					flags |= ISPRIVATE;
+					break;
+				}
+				errorp("static declaration of '%s' follows non-static declaration",
+				       name);
 				break;
 			}
 		}
+		sym->flags = flags;
 	} else {
+		sym->type = tp;
+		sym->u.pars = dcl->pars;
 		flags = sym->flags;
+
 		switch (sclass) {
 		case REGISTER:
 		case AUTO:
-			if (curctx == GLOBALCTX || tp->op == FTN)
-				goto bad_storage;
+			if (curctx == GLOBALCTX || tp->op == FTN) {
+				bad_storage(tp, name);
+				break;
+			}
 			flags |= (sclass == REGISTER) ? ISREGISTER : ISAUTO;
 			break;
 		case NOSCLASS:
@@ -623,12 +645,9 @@
 			sym->token = TYPEIDEN;
 			break;
 		}
+		sym->flags = flags;
 	}
 
-	sym->u.pars = dcl->pars;
-	sym->flags = flags;
-	sym->type = tp;
-
 	if (accept('='))
 		initializer(sym);
 	/* TODO: disallow initializators in functions */
@@ -639,21 +658,8 @@
 	return sym;
 
 redeclaration:
-	error("redeclaration of '%s'", name);
-
-bad_storage:
-	if (tp->op != FTN)
-		error("incorrect storage class for file-scope declaration");
-bad_function:
-	error("invalid storage class for function '%s'", name);
-
-non_after_static:
-	error("non-static declaration of '%s' follows static declaration",
-	      name);
-
-static_after_non:
-	error("static declaration of '%s' follows non-static declaration",
-	      name);
+	errorp("redeclaration of '%s'", name);
+	return sym;
 }
 
 static Symbol *
@@ -728,6 +734,7 @@
 		prototype:
 			emit(ODECL, sym);
 			free(sym->u.pars);
+			sym->u.pars = NULL;
 			popctx();
 		}
 	}
--- a/cc1/error.c
+++ b/cc1/error.c
@@ -24,6 +24,10 @@
 	putc('\n', stderr);
 
 	if (flag < 0) {
+		if (!failure) {
+			failure = 1;
+			puts("????");
+		}
 		failure = 1;
 		if (nerrors++ == MAXERRNUM) {
 			fputs("too many errors\n", stderr);
@@ -56,7 +60,7 @@
 }
 
 void
-printerr(char *fmt, ...)
+errorp(char *fmt, ...)
 {
 	va_list va;
 	va_start(va, fmt);
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -550,9 +550,9 @@
 {
 	if (yytoken != tok) {
 		if (isgraph(tok))
-			printerr("expected '%c' before '%s'", tok, yytext);
+			errorp("expected '%c' before '%s'", tok, yytext);
 		else
-			printerr("unexpected '%s'", yytext);
+			errorp("unexpected '%s'", yytext);
 	} else {
 		next();
 	}
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -113,7 +113,7 @@
 			if ((f & (ISUSED|ISDEFINED)) == ISDEFINED)
 				warn("'%s' defined but not used", sym->name);
 			if ((f & ISDEFINED) == 0)
-				printerr("label '%s' is not defined", sym->name);
+				errorp("label '%s' is not defined", sym->name);
 			free(sym->name);
 			free(sym);
 		}
--- /dev/null
+++ b/cc1/tests/test013.c
@@ -1,0 +1,271 @@
+/*
+name: TEST013
+description: Basic test of integer types and integer conversions
+comments: This test depends of the configuration in the type system.
+          With the current configuration char is equal to unsigned char,
+          short is equal to int, and unsigned short is equal to unsigned.
+output:
+G1	I	a
+G2	N	b
+G3	M	c
+G4	C	d
+G5	M	e
+G6	W	f
+G7	Z	g
+G8	Q	h
+G9	O	i
+G10	I	j
+G11	N	k
+F1
+G12	F1	main
+{
+-
+	G1	G2	NI	:I
+	G1	G3	MI	:I
+	G1	G4	CI	:I
+	G1	G5	MI	:I
+	G1	G6	WI	:I
+	G1	G7	ZI	:I
+	G1	G8	QI	:I
+	G1	G9	OI	:I
+	G1	G10	:I
+	G1	G11	NI	:I
+	G2	G1	IN	:N
+	G2	G3	MN	:N
+	G2	G4	CN	:N
+	G2	G5	MN	:N
+	G2	G6	WN	:N
+	G2	G7	ZN	:N
+	G2	G8	QN	:N
+	G2	G9	ON	:N
+	G2	G10	IN	:N
+	G2	G11	:N
+	G3	G1	IM	:M
+	G3	G2	NM	:M
+	G3	G4	CM	:M
+	G3	G5	:M
+	G3	G6	WM	:M
+	G3	G7	ZM	:M
+	G3	G8	QM	:M
+	G3	G9	OM	:M
+	G3	G10	IM	:M
+	G3	G11	NM	:M
+	G4	G1	IC	:C
+	G4	G2	NC	:C
+	G4	G3	MC	:C
+	G4	G5	MC	:C
+	G4	G6	WC	:C
+	G4	G7	ZC	:C
+	G4	G8	QC	:C
+	G4	G9	OC	:C
+	G4	G10	IC	:C
+	G4	G11	NC	:C
+	G5	G1	IM	:M
+	G5	G2	NM	:M
+	G5	G3	:M
+	G5	G4	CM	:M
+	G5	G6	WM	:M
+	G5	G7	ZM	:M
+	G5	G8	QM	:M
+	G5	G9	OM	:M
+	G5	G10	IM	:M
+	G5	G11	NM	:M
+	G6	G1	IW	:W
+	G6	G2	NW	:W
+	G6	G3	MW	:W
+	G6	G4	CW	:W
+	G6	G5	MW	:W
+	G6	G7	ZW	:W
+	G6	G8	QW	:W
+	G6	G9	OW	:W
+	G6	G10	IW	:W
+	G6	G11	NW	:W
+	G7	G1	IZ	:Z
+	G7	G2	NZ	:Z
+	G7	G3	MZ	:Z
+	G7	G4	CZ	:Z
+	G7	G5	MZ	:Z
+	G7	G6	WZ	:Z
+	G7	G8	QZ	:Z
+	G7	G9	OZ	:Z
+	G7	G10	IZ	:Z
+	G7	G11	NZ	:Z
+	G8	G1	IQ	:Q
+	G8	G2	NQ	:Q
+	G8	G3	MQ	:Q
+	G8	G4	CQ	:Q
+	G8	G5	MQ	:Q
+	G8	G6	WQ	:Q
+	G8	G7	ZQ	:Q
+	G8	G9	OQ	:Q
+	G8	G10	IQ	:Q
+	G8	G11	NQ	:Q
+	G9	G1	IO	:O
+	G9	G2	NO	:O
+	G9	G3	MO	:O
+	G9	G4	CO	:O
+	G9	G5	MO	:O
+	G9	G6	WO	:O
+	G9	G7	ZO	:O
+	G9	G8	QO	:O
+	G9	G10	IO	:O
+	G9	G11	NO	:O
+	G10	G1	:I
+	G10	G2	NI	:I
+	G10	G3	MI	:I
+	G10	G4	CI	:I
+	G10	G5	MI	:I
+	G10	G6	WI	:I
+	G10	G7	ZI	:I
+	G10	G8	QI	:I
+	G10	G9	OI	:I
+	G10	G11	NI	:I
+	G11	G1	IN	:N
+	G11	G2	:N
+	G11	G3	MN	:N
+	G11	G4	CN	:N
+	G11	G5	MN	:N
+	G11	G6	WN	:N
+	G11	G7	ZN	:N
+	G11	G8	QN	:N
+	G11	G10	IN	:N
+	G11	G9	ON	:N
+}
+*/
+
+int a;
+unsigned b;
+char c;
+signed char d;
+unsigned char e;
+long f;
+unsigned long g;
+long long h;
+unsigned long long i;
+short j;
+unsigned short k;
+
+int
+main(void)
+{
+	a = b;
+	a = c;
+	a = d;
+	a = e;
+	a = f;
+	a = g;
+	a = h;
+	a = i;
+	a = j;
+	a = k;
+
+	b = a;
+	b = c;
+	b = d;
+	b = e;
+	b = f;
+	b = g;
+	b = h;
+	b = i;
+	b = j;
+	b = k;
+
+	c = a;
+	c = b;
+	c = d;
+	c = e;
+	c = f;
+	c = g;
+	c = h;
+	c = i;
+	c = j;
+	c = k;
+
+	d = a;
+	d = b;
+	d = c;
+	d = e;
+	d = f;
+	d = g;
+	d = h;
+	d = i;
+	d = j;
+	d = k;
+
+	e = a;
+	e = b;
+	e = c;
+	e = d;
+	e = f;
+	e = g;
+	e = h;
+	e = i;
+	e = j;
+	e = k;
+
+	f = a;
+	f = b;
+	f = c;
+	f = d;
+	f = e;
+	f = g;
+	f = h;
+	f = i;
+	f = j;
+	f = k;
+
+	g = a;
+	g = b;
+	g = c;
+	g = d;
+	g = e;
+	g = f;
+	g = h;
+	g = i;
+	g = j;
+	g = k;
+
+	h = a;
+	h = b;
+	h = c;
+	h = d;
+	h = e;
+	h = f;
+	h = g;
+	h = i;
+	h = j;
+	h = k;
+
+	i = a;
+	i = b;
+	i = c;
+	i = d;
+	i = e;
+	i = f;
+	i = g;
+	i = h;
+	i = j;
+	i = k;
+
+	j = a;
+	j = b;
+	j = c;
+	j = d;
+	j = e;
+	j = f;
+	j = g;
+	j = h;
+	j = i;
+	j = k;
+
+	k = a;
+	k = b;
+	k = c;
+	k = d;
+	k = e;
+	k = f;
+	k = g;
+	k = h;
+	k = j;
+	k = i;
+}
--- /dev/null
+++ b/cc1/tests/test014.c
@@ -1,0 +1,86 @@
+/*
+name: TEST014
+description: Basic storage class test
+output:
+test014.c:22: warning: 'a' defined but not used
+test014.c:22: warning: 'k' defined but not used
+test014.c:22: warning: 'j' defined but not used
+test014.c:22: warning: 'i' defined but not used
+test014.c:22: warning: 'h' defined but not used
+test014.c:28: warning: 'par' defined but not used
+test014.c:28: warning: 'par' defined but not used
+test014.c:33: warning: 'par' defined but not used
+test014.c:35: error: incorrect storage class for file-scope declaration
+test014.c:35: error: invalid storage class for function 'd'
+test014.c:38: error: bad storage class in function parameter
+test014.c:39: error: invalid storage class for function 'func4'
+test014.c:40: error: invalid type specification
+test014.c:41: warning: 'f' defined but not used
+test014.c:44: error: conflicting types for 'd'
+G1	I	a
+Y2	M	b
+X3	I	c
+F1
+G5	F1	func1
+{
+-
+A2	I	h
+T3	M	i
+R4	W	j
+X5	I	k
+T6	Z	a
+	yI	#I0
+}
+F2	I
+G6	F2	func2
+{
+R1	I	par
+-
+A3	I	par
+}
+T7	F2	func3
+{
+R1	I	par
+-
+}
+????
+*/
+
+int a;
+static char b;
+extern int c;
+typedef unsigned e;
+
+int
+func1(void)
+{
+	auto h;
+	static char i;
+	register long j;
+	extern int k;
+	static unsigned long a;
+	return 0;
+}
+
+void
+func2(register int par)
+{
+	int par;
+}
+
+static void
+func3(register int par)
+{
+}
+
+register short d;
+
+register void
+func4(static int par)
+{
+	static register f;
+}
+
+short d;
+char d;
+