20050124 Dave Dodge tcc 0.9.22 doesn't properly handle the following construct: typedef [...] a; typedef [...] b; [...] foo([...]) { a b; /* not parsed correctly */ } The problem is that it parses both "a" and "b" as typedef names, and does nothing as a result. Although the C99 grammar allows this parsing, there is a constraint in the narrative that invalidates it and requires "b" to be treated as a declarator. This patch causes tcc to stop looking for typedef names in a declaration specifier list after it finds the first one; the end result should be that "b" becomes a local variable and hides the "b" typedef while in scope. --- tcc-0.9.22/tcc.c 2004-11-08 15:47:16.000000000 -0500 +++ tcc-0.9.22-patched/tcc.c 2005-01-24 23:08:04.000000000 -0500 @@ -6497,13 +6497,14 @@ */ static int parse_btype(CType *type, AttributeDef *ad) { - int t, u, type_found, typespec_found; + int t, u, type_found, typespec_found, typedef_found; Sym *s; CType type1; memset(ad, 0, sizeof(AttributeDef)); type_found = 0; typespec_found = 0; + typedef_found = 0; t = 0; while(1) { switch(tok) { @@ -6638,9 +6639,15 @@ default: if (typespec_found) goto the_end; + if (typedef_found) + /* we've already found a typedef-name in the declaration */ + /* specifier list, so ignore any further ones and treat */ + /* them as plain identifiers */ + goto the_end; s = sym_find(tok); if (!s || !(s->type.t & VT_TYPEDEF)) goto the_end; + typedef_found = 1; t |= (s->type.t & ~VT_TYPEDEF); type->ref = s->type.ref; next();