commit 3dca060d1ad6e41aa5ec4c4bc26bfff2fff54a1d
parent af0a60913386396971fb0c4311370d68ae247c26
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 11 Jul 2014 09:50:31 +0200
Allow labels with same name that a previous typedef
Labels have a separate namespace, so it is correct this combination,
but the problem is the lexer returns a different token for an
identifier after a typedef for it. For example:
main()
{
typedef int pepe;
pepe: return 0;
}
The easier solution is a hack, where we modify the grammar to
accept an IDEN or a TYPE when creating labels.
Diffstat:
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -170,11 +170,16 @@ static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
static void
Label(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
- emitlabel(label(yytext, 1));
-
- expect(IDEN);
- expect(':');
- stmt(lbreak, lcont, lswitch);
+ switch (yytoken) {
+ case IDEN: case TYPE:
+ emitlabel(label(yytext, 1));
+ next();
+ expect(':');
+ stmt(lbreak, lcont, lswitch);
+ break;
+ default:
+ unexpected();
+ }
}
static void
@@ -297,10 +302,15 @@ compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
case '}':
next();
return;
- case TYPE: case SCLASS: case TQUALIFIER:
+ case TYPE:
+ if (ahead() == ':')
+ goto statement;
+ /* pass through */
+ case SCLASS: case TQUALIFIER:
decl();
break;
default:
+ statement:
stmt(lbreak, lcont, lswitch);
}
}
@@ -325,7 +335,9 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
case CASE: fun = Case; break;
case DEFAULT: fun = Default; break;
default: fun = stmtexp; break;
- case IDEN: fun = (ahead() == ':') ? Label : stmtexp; break;
+ case TYPE: case IDEN:
+ fun = (ahead() == ':') ? Label : stmtexp;
+ break;
}
(*fun)(lbreak, lcont, lswitch);
}