[hackers] [scc] Fix errors in reuse of non defined symbols || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Fri, 21 Aug 2015 13:10:37 +0200 (CEST)

X-DEBUG-UPD: 98caf6b9f86aa7e0af46d9de891e467364be6d2d
commit 98caf6b9f86aa7e0af46d9de891e467364be6d2d
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Tue Aug 18 19:09:12 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Tue Aug 18 19:09:12 2015 +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.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index 2ef79b8..3ef22c4 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -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
index bbfbb27..b5fd7a1 100644
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
_AT_@ -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;
 }
_AT_@ -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
index 34bccb1..222e817 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -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
index a008f2b..6c0b29a 100644
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
_AT_@ -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(':');
_AT_@ -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();
_AT_@ -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('(');
_AT_@ -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);
_AT_@ -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(';');
 }
_AT_@ -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);
_AT_@ -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");
_AT_@ -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(':');
_AT_@ -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
index e2e7e0f..45e481a 100644
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
_AT_@ -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);
_AT_@ -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;
_AT_@ -180,7 +180,6 @@ newsym(unsigned ns)
                 return sym;
         if (ns == NS_LABEL) {
                 sym->next = labels;
- sym->id = newid();
                 return labels = sym;
         }
 
_AT_@ -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)
_AT_@ -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;
 }
_AT_@ -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;
 }
_AT_@ -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
index 6295d37..2347d30 100644
--- a/cc1/tests/test011.c
+++ b/cc1/tests/test011.c
_AT_@ -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
index 0457aa8..f1c9f3e 100644
--- a/cc1/tests/test012.c
+++ b/cc1/tests/test012.c
_AT_@ -2,6 +2,7 @@
 name: TEST012
 description: Basic switch test
 output:
+test012.c:39: warning: 'foo' defined but not used
 F1
 G1 F1 main
 {
_AT_@ -70,7 +71,7 @@ L21
 }
 */
 
-
+#line 1
 
 int
 main()
Received on Fri Aug 21 2015 - 13:10:37 CEST

This archive was generated by hypermail 2.3.0 : Fri Aug 21 2015 - 13:12:25 CEST