commit 8182a159c71c03a6cd28b9c8651c26db5e1743c4
parent 6650268eca2441b777636a3aad411b2d70e23281
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 21 Aug 2015 13:08:20 +0200
Merge remote-tracking branch 'origin/master'
Conflicts:
cc1/symbol.c
Diffstat:
8 files changed, 411 insertions(+), 43 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -300,7 +300,7 @@ enum op {
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 */
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -628,7 +628,7 @@ cpp(void)
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;
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -128,7 +128,8 @@ parameter(struct decl *dcl)
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 @@ specifier(int *sclass)
break;
case TQUALIFIER:
if (qlf && qlf != RESTRICT)
- goto invalid_type;
+ errorp("invalid type specification");
qlf |= yylval.token;
next();
continue;
@@ -319,11 +320,11 @@ specifier(int *sclass)
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_type:
}
}
return tp;
-
-invalid_type:
- error("invalid type specification");
}
/* TODO: check correctness of the initializator */
@@ -528,6 +526,14 @@ field(struct decl *dcl)
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 @@ identifier(struct decl *dcl)
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 @@ identifier(struct decl *dcl)
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 @@ identifier(struct decl *dcl)
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 @@ identifier(struct decl *dcl)
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 @@ decl(void)
prototype:
emit(ODECL, sym);
free(sym->u.pars);
+ sym->u.pars = NULL;
popctx();
}
}
diff --git a/cc1/error.c b/cc1/error.c
@@ -24,6 +24,10 @@ warn_error(int flag, char *fmt, va_list va)
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 @@ error(char *fmt, ...)
}
void
-printerr(char *fmt, ...)
+errorp(char *fmt, ...)
{
va_list va;
va_start(va, fmt);
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -550,9 +550,9 @@ expect(unsigned tok)
{
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();
}
diff --git a/cc1/symbol.c b/cc1/symbol.c
@@ -113,7 +113,7 @@ popctx(void)
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);
}
diff --git a/cc1/tests/test013.c b/cc1/tests/test013.c
@@ -0,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;
+}
diff --git a/cc1/tests/test014.c b/cc1/tests/test014.c
@@ -0,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;
+