From: Marek Polacek Date: Thu, 12 Nov 2015 21:07:04 +0000 (+0000) Subject: re PR c/67784 (Incorrect parsing when using declarations in for loops and typedefs) X-Git-Tag: basepoints/gcc-7~3052 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9be4f715f4db43da3585dfbfaa4545e5b1e07dc1;p=thirdparty%2Fgcc.git re PR c/67784 (Incorrect parsing when using declarations in for loops and typedefs) PR c/67784 * c-parser.c (c_parser_for_statement): Reclassify the token in a correct scope. * gcc.dg/pr67784-1.c: New test. * gcc.dg/pr67784-2.c: New test. From-SVN: r230273 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 87f6a2d30e3b..0191b4553981 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2015-11-12 Marek Polacek + + PR c/67784 + * c-parser.c (c_parser_for_statement): Reclassify the token in + a correct scope. + 2015-11-11 Marek Polacek PR c/68107 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 2484b920fad3..89498254b785 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -5749,6 +5749,21 @@ c_parser_for_statement (c_parser *parser, bool ivdep) c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ())); + /* We might need to reclassify any previously-lexed identifier, e.g. + when we've left a for loop with an if-statement without else in the + body - we might have used a wrong scope for the token. See PR67784. */ + if (c_parser_next_token_is (parser, CPP_NAME)) + { + c_token *token = c_parser_peek_token (parser); + tree decl = lookup_name (token->value); + if (decl == NULL_TREE) + ; + 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 = get_token_indent_info (c_parser_peek_token (parser)); warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 680b9def71f3..ac1aa6c64984 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-11-12 Marek Polacek + + PR c/67784 + * gcc.dg/pr67784-1.c: New test. + * gcc.dg/pr67784-2.c: New test. + 2015-11-12 Martin Liska * gcc.dg/ipa/pr68035.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr67784-1.c b/gcc/testsuite/gcc.dg/pr67784-1.c new file mode 100644 index 000000000000..d5e85fc0c8b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67784-1.c @@ -0,0 +1,54 @@ +/* PR c/67784 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef int T; + +void +fn1 (void) +{ + for (int T;;) + if (1) + ; + T *x; +} + +void +fn2 (void) +{ + for (int T;;) + if (1) + T = 1; + T *x; +} + +void +fn3 (void) +{ + for (int T;;) + if (1) + { + } + T *x; +} + +void +fn4 (void) +{ + for (int T;;) + if (1) +L: + ; + T *x; +} + +void +fn5 (void) +{ + for (int T;;) + if (1) + ; + else + ; + T *x; +} diff --git a/gcc/testsuite/gcc.dg/pr67784-2.c b/gcc/testsuite/gcc.dg/pr67784-2.c new file mode 100644 index 000000000000..de3b1c89a89c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67784-2.c @@ -0,0 +1,54 @@ +/* PR c/67784 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int T; + +void +fn1 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + T *x; /* { dg-error "undeclared" } */ +} + +void +fn2 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + T = 1; /* { dg-error "expected expression" } */ + T *x; /* { dg-error "undeclared" } */ +} + +void +fn3 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + { + } + T *x; /* { dg-error "undeclared" } */ +} + +void +fn4 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) +L: + ; + T *x; /* { dg-error "undeclared" } */ +} + +void +fn5 (void) +{ + for (typedef int T;;) /* { dg-error "declaration of non-variable" } */ + if (1) + ; + else + ; + T *x; /* { dg-error "undeclared" } */ +}