scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

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:
cc1/cc1.h | 2+-
cc1/cpp.c | 2+-
cc1/decl.c | 81+++++++++++++++++++++++++++++++++++++++++++------------------------------------
cc1/error.c | 6+++++-
cc1/lex.c | 4++--
cc1/symbol.c | 2+-
cc1/tests/test013.c | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cc1/tests/test014.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +