While fixing c/67784 I noticed that the following testcase was breaking because we ended up with a TYPENAME whose name is NULL. In c_parser_declspecs: 2301 /* For a typedef name, record the meaning, not the name. 2302 In case of 'foo foo, bar;'. */ 2303 t.spec = lookup_name (value); we pass T to declspecs_add_type and that segvs when t.spec is NULL.
I think this is best fixed by treating such tokens as IDs and let subsequent code error on such an invalid code with proper diagnostics. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-11-13 Marek Polacek <pola...@redhat.com> PR c/68320 * c-parser.c (c_parser_for_statement): Treat unknown tokens as IDs. * gcc.dg/pr68320.c: New test. diff --git gcc/c/c-parser.c gcc/c/c-parser.c index c01d651..82d5ce5 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -5757,12 +5757,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep) { c_token *token = c_parser_peek_token (parser); tree decl = lookup_name (token->value); - if (decl == NULL_TREE) - ; + if (decl == NULL_TREE || VAR_P (decl)) + /* If DECL is null, we don't know what this token might be. Treat + it as an ID for better diagnostics; we'll error later on. */ + token->id_kind = C_ID_ID; else if (TREE_CODE (decl) == TYPE_DECL) token->id_kind = C_ID_TYPENAME; - else if (VAR_P (decl)) - token->id_kind = C_ID_ID; } token_indent_info next_tinfo diff --git gcc/testsuite/gcc.dg/pr68320.c gcc/testsuite/gcc.dg/pr68320.c index e69de29..7060af8 100644 --- gcc/testsuite/gcc.dg/pr68320.c +++ gcc/testsuite/gcc.dg/pr68320.c @@ -0,0 +1,67 @@ +/* PR c/68320 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +fn1 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T x; /* { dg-error "unknown type name" } */ +} + +void +fn2 (int i) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + i = 5; + T x; /* { dg-error "unknown type name" } */ +} + +void +fn3 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + { + } + T *x; /* { dg-error "unknown type name" } */ +} + +void +fn4 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T, T; /* { dg-error "undeclared" } */ +} + +void +fn5 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T = 10; /* { dg-error "undeclared" } */ +} + +void +fn6 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T[0]; /* { dg-error "undeclared" } */ +} + +void +fn7 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T (); /* { dg-warning "implicit declaration" } */ +} Marek