commit 98caf6b9f86aa7e0af46d9de891e467364be6d2d
parent d6954f1a841ffe95aacc8c0e8a9dca44a087b1a6
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 18 Aug 2015 19:09:12 +0200
Fix errors in reuse of non defined symbols
There were several errors when a symbol reused some previous
non declared symbol in a different namespace, because it was
not covering the possibility that the symbol already existed.
Diffstat:
7 files changed, 61 insertions(+), 46 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -311,13 +311,14 @@ extern Type *duptype(Type *base);
/* symbol.c */
extern void dumpstab(char *msg);
-extern Symbol *lookup(unsigned ns);
+extern Symbol *lookup(unsigned ns, char *name);
extern Symbol *nextsym(Symbol *sym, unsigned ns);
extern Symbol *install(unsigned ns, Symbol *sym);
extern Symbol *newsym(unsigned ns);
extern void pushctx(void), popctx(void);
extern void ikeywords(void);
extern void delmacro(Symbol *sym);
+extern Symbol *newlabel(void);
/* stmt.c */
extern void compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -29,7 +29,7 @@ defmacro(char *s)
Symbol *sym;
strcpy(yytext, s);
- sym = lookup(NS_CPP);
+ sym = lookup(NS_CPP, yytext);
sym->flags |= ISDECLARED;
return sym;
}
@@ -338,7 +338,7 @@ define(void)
warn("'%s' redefined", yytext);
free(sym->u.s);
} else {
- sym = lookup(NS_CPP);
+ sym = lookup(NS_CPP, yytext);
sym->flags |= ISDECLARED;
}
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -378,7 +378,7 @@ iden(void)
/* nothing */;
input->p = p;
tok2str();
- sym = lookup(lex_ns);
+ sym = lookup(lex_ns, yytext);
if (sym->ns == NS_CPP) {
if (!disexpand && expand(begin, sym))
return next();
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -22,6 +22,7 @@ label(void)
case TYPEIDEN:
if ((sym = install(NS_LABEL, yylval.sym)) == NULL)
error("label '%s' already defined", yytoken);
+ sym->flags |= ISDEFINED;
emit(OLABEL, sym);
next();
expect(':');
@@ -51,9 +52,9 @@ While(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
Symbol *begin, *cond, *end;
Node *np;
- begin = newsym(NS_LABEL);
- end = newsym(NS_LABEL);
- cond = newsym(NS_LABEL);
+ begin = newlabel();
+ end = newlabel();
+ cond = newlabel();
expect(WHILE);
np = condition();
@@ -74,9 +75,9 @@ For(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
Symbol *begin, *cond, *end;
Node *econd, *einc, *einit;
- begin = newsym(NS_LABEL);
- end = newsym(NS_LABEL);
- cond = newsym(NS_LABEL);
+ begin = newlabel();
+ end = newlabel();
+ cond = newlabel();
expect(FOR);
expect('(');
@@ -106,8 +107,8 @@ Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
Symbol *begin, *end;
Node *np;
- begin = newsym(NS_LABEL);
- end = newsym(NS_LABEL);
+ begin = newlabel();
+ end = newlabel();
expect(DO);
emit(OBLOOP, NULL);
emit(OLABEL, begin);
@@ -166,12 +167,17 @@ Continue(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
static void
Goto(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
+ Symbol *sym;
+
setnamespace(NS_LABEL);
next();
if (yytoken != IDEN)
unexpected();
- yylval.sym->flags |= ISUSED;
- emit(OJUMP, yylval.sym);
+ sym = yylval.sym;
+ if ((sym->flags & ISDECLARED) == 0)
+ sym = install(NS_LABEL, sym);
+ sym->flags |= ISUSED;
+ emit(OJUMP, sym);
next();
expect(';');
}
@@ -198,8 +204,8 @@ Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
expect (')');
lcase.expr = cond;
- lcase.lbreak = newsym(NS_LABEL);
- lcase.ltable = newsym(NS_LABEL);
+ lcase.lbreak = newlabel();
+ lcase.ltable = newlabel();
emit(OSWITCH, &lcase);
stmt(lbreak, lcont, &lcase);
@@ -224,7 +230,7 @@ Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
pcase = xmalloc(sizeof(*pcase));
pcase->expr = np;
pcase->next = lswitch->head;
- emit(OLABEL, pcase->label = newsym(NS_LABEL));
+ emit(OLABEL, pcase->label = newlabel());
lswitch->head = pcase;
if (++lswitch->nr == NR_SWITCH)
error("too case labels for a switch statement");
@@ -234,7 +240,7 @@ Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
static void
Default(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
- Symbol *ldefault = newsym(NS_LABEL);
+ Symbol *ldefault = newlabel();
expect(DEFAULT);
expect(':');
@@ -250,14 +256,14 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
Symbol *end, *lelse;
Node *np;
- lelse = newsym(NS_LABEL);
+ lelse = newlabel();
expect(IF);
np = condition();
emit(OBRANCH, lelse);
emit(OEXPR, negate(np));
stmt(lbreak, lcont, lswitch);
if (accept(ELSE)) {
- end = newsym(NS_LABEL);
+ end = newlabel();
emit(OJUMP, end);
emit(OLABEL, lelse);
stmt(lbreak, lcont, lswitch);
diff --git a/cc1/symbol.c b/cc1/symbol.c
@@ -110,9 +110,9 @@ popctx(void)
for (sym = labels; sym; sym = next) {
next = sym->next;
f = sym->flags;
- if ((f & (ISUSED|ISDECLARED)) == ISDECLARED)
+ if ((f & (ISUSED|ISDEFINED)) == ISDEFINED)
warn("'%s' defined but not used", sym->name);
- if ((f & ISDECLARED) == 0)
+ if ((f & ISDEFINED) == 0)
printerr("label '%s' is not defined", sym->name);
free(sym->name);
free(sym);
@@ -171,7 +171,7 @@ newsym(unsigned ns)
sym->ns = ns;
sym->ctx = (ns == NS_CPP) ? UCHAR_MAX : curctx;
sym->token = IDEN;
- sym->flags = ISDECLARED;
+ sym->flags = ISDECLARED | ISUSED;
sym->u.s = sym->name = NULL;
sym->type = NULL;
sym->next = sym->hash = NULL;
@@ -180,7 +180,6 @@ newsym(unsigned ns)
return sym;
if (ns == NS_LABEL) {
sym->next = labels;
- sym->id = newid();
return labels = sym;
}
@@ -201,18 +200,27 @@ newsym(unsigned ns)
}
Symbol *
-lookup(unsigned ns)
+newlabel(void)
+{
+ Symbol *sym = newsym(NS_LABEL);
+ sym->id = newid();
+ sym->flags |= ISDEFINED;
+ return sym;
+}
+
+Symbol *
+lookup(unsigned ns, char *name)
{
Symbol *sym, **h;
unsigned sns, v;
char *t, c;
- v = hash(yytext);
+ v = hash(name);
h = &htab[v];
- c = *yytext;
+ c = *name;
for (sym = *h; sym; sym = sym->hash) {
t = sym->name;
- if (*t != c || strcmp(t, yytext))
+ if (*t != c || strcmp(t, name))
continue;
sns = sym->ns;
if (sns == NS_KEYWORD || sns == NS_CPP)
@@ -221,8 +229,8 @@ lookup(unsigned ns)
continue;
return sym;
}
- sym = linkhash(newsym(ns), yytext, v);
- sym->flags &= ~ISDECLARED;
+ sym = linkhash(newsym(ns), name, v);
+ sym->flags &= ~(ISDECLARED | ISUSED);
return sym;
}
@@ -263,21 +271,19 @@ nextsym(Symbol *sym, unsigned ns)
Symbol *
install(unsigned ns, Symbol *sym)
{
- if (sym->ctx == curctx) {
- if (sym->flags & ISDECLARED) {
- if (ns == sym->ns)
- return NULL;
- } else {
- sym->flags |= ISDECLARED;
- sym->ns = ns;
- goto assign_id;
- }
+ if (sym->ctx == curctx && ns == sym->ns) {
+ if (sym->flags & ISDECLARED)
+ return NULL;
+ } else {
+ sym = lookup(ns, sym->name);
+ if (sym->flags & ISDECLARED)
+ return sym;
}
- sym = linkhash(newsym(ns), sym->name, hash(sym->name));
-assign_id:
- if (sym->ns != NS_CPP || sym->ns != NS_LABEL)
- sym->id = newid();
+ sym->flags |= ISDECLARED;
+ if (ns == NS_CPP)
+ return sym;
+ sym->id = newid();
return sym;
}
@@ -348,8 +354,7 @@ ikeywords(void)
for (lp = list; *lp; ++lp) {
for (bp = *lp; bp->str; ++bp) {
- strcpy(yytext, bp->str);
- sym = lookup(ns);
+ sym = lookup(ns, bp->str);
sym->token = bp->token;
sym->u.token = bp->value;
}
diff --git a/cc1/tests/test011.c b/cc1/tests/test011.c
@@ -2,6 +2,8 @@
name: TEST011
description: Basic test for goto
output:
+test011.c:14: warning: 'foo' defined but not used
+test011.c:14: warning: 'start' defined but not used
F1
G1 F1 main
{
diff --git a/cc1/tests/test012.c b/cc1/tests/test012.c
@@ -2,6 +2,7 @@
name: TEST012
description: Basic switch test
output:
+test012.c:39: warning: 'foo' defined but not used
F1
G1 F1 main
{
@@ -70,7 +71,7 @@ L21
}
*/
-
+#line 1
int
main()