scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit f6d8f8f304878b3c0e4544d055b29482f818f13e
parent 9b1eafb87ca51b32030a2a53bed3f2170bf2f936
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 13 Aug 2015 16:21:01 +0200

Fix #if with not defined macros

When a not defined macro appears in a #if then it must be evaluated
to 0.

Diffstat:
Mcc1/cpp.c | 17+++++++++++++++++
Mcc1/lex.c | 10+++++++---
2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/cc1/cpp.c b/cc1/cpp.c @@ -195,6 +195,16 @@ expand(char *begin, Symbol *sym) char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE]; macroname = sym->name; + if (!(sym->flags & ISDECLARED)) { + /* + * This case happens in #if were macro not defined must + * be expanded to 0 + */ + buffer[0] = '0'; + buffer[1] = '\0'; + elen = 1; + goto substitute; + } if (sym == symfile) { elen = sprintf(buffer, "\"%s\" ", input->fname); goto substitute; @@ -231,6 +241,9 @@ substitute: input->p = input->begin = begin; + if (!(sym->flags & ISDECLARED)) + delmacro(sym); + return 1; } #undef BUFSIZE @@ -327,6 +340,7 @@ define(void) sym->flags |= ISDECLARED; } + setnamespace(NS_IDEN); /* Avoid polution in NS_CPP */ next(); if ((n = getpars(args)) == NR_MACROARG) goto delete; @@ -502,6 +516,7 @@ static void cppif(void) { setnamespace(NS_CPP); + disexpand = 0; next(); ifclause(0, 0); } @@ -548,6 +563,8 @@ elseclause(void) static void elif(void) { + setnamespace(NS_CPP); + disexpand = 0; elseclause(); ifclause(0, 0); } diff --git a/cc1/lex.c b/cc1/lex.c @@ -18,7 +18,7 @@ unsigned short yylen; int cppoff; int lexmode = CCMODE; -static unsigned lex_ns = NS_IDEN; +static unsigned lex_ns = NS_IDEN, saved_ns; static int safe, eof; Input *input; @@ -380,7 +380,7 @@ iden(void) input->p = p; tok2str(); sym = lookup(lex_ns); - if (sym->ns == NS_CPP && lexmode == CCMODE) { + if (sym->ns == NS_CPP) { if (!disexpand && expand(begin, sym)) return next(); /* @@ -493,6 +493,7 @@ operator(void) void setnamespace(int ns) { + saved_ns = (ns == NS_CPPCLAUSES) ? lex_ns : 0; lex_ns = ns; } @@ -518,6 +519,8 @@ next(void) skipspaces(); c = *input->begin; if ((eof || lexmode == CPPMODE) && c == '\0') { + if (lexmode == CPPMODE) + lex_ns = saved_ns; strcpy(yytext, "<EOF>"); if (cppctx && eof) error("#endif expected"); @@ -538,7 +541,8 @@ next(void) exit: DBG(stderr, "TOKEN %s\n", yytext); - lex_ns = NS_IDEN; + if (lexmode == CCMODE) + lex_ns = NS_IDEN; return yytoken; }