diff options
author | Joseph Myers <josmyers@redhat.com> | 2024-11-27 22:27:08 +0000 |
---|---|---|
committer | Joseph Myers <josmyers@redhat.com> | 2024-11-27 22:27:08 +0000 |
commit | 87492fb3fd5e7510983e0275a38ba95769335018 (patch) | |
tree | a692b68da2b695c493e8c6a930ea5d6db78d7f67 /gcc/c/c-parser.cc | |
parent | 73e5d2f87c257c2c12ee72fd4de9bdbb6a8e1aa9 (diff) | |
download | gcc-87492fb3fd5e7510983e0275a38ba95769335018.zip gcc-87492fb3fd5e7510983e0275a38ba95769335018.tar.gz gcc-87492fb3fd5e7510983e0275a38ba95769335018.tar.bz2 |
c: Fix ICE using function name in parameter type in old-style function definition [PR91193]
As reported in bug 91193, if an old-style function definition
redeclares a typedef name as a function, then uses that function name
at the start of the first old-style parameter definition, then the
parser interprets that token as a typedef name (because lookahead
occurred before processing of the function declarator completed), but
when it is looked up in processing that parameter definition, what is
found is the redefinition, resulting in an ICE.
The function name's scope starts at the end of its declarator, so this
is similar to other cases where we call
c_parser_maybe_reclassify_token because lookahead might have
classified a token as being a typedef or not based on information from
the wrong scope; do so in this case as well, so resulting in the
expected parse errors from using something that's no longer a typedef
name as if it were a typedef name, and eliminating the ICE.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
PR c/91193
gcc/c/
* c-parser.cc (c_parser_maybe_reclassify_token): Define earlier.
(c_parser_declaration_or_fndef): Call
c_parser_maybe_reclassify_token before parsing old-style parameter
definitions.
gcc/testsuite/
* gcc.dg/pr91193-1.c, gcc.dg/pr91193-2.c: New tests.
Diffstat (limited to 'gcc/c/c-parser.cc')
-rw-r--r-- | gcc/c/c-parser.cc | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 0e6f87e..6eaea2c 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -2129,6 +2129,43 @@ handle_assume_attribute (location_t here, tree attrs, bool nested) return remove_attribute ("gnu", "assume", attrs); } +/* 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. */ + +static void +c_parser_maybe_reclassify_token (c_parser *parser) +{ + if (c_parser_next_token_is (parser, CPP_NAME)) + { + c_token *token = c_parser_peek_token (parser); + + if (token->id_kind != C_ID_CLASSNAME) + { + tree decl = lookup_name (token->value); + + token->id_kind = C_ID_ID; + if (decl) + { + if (TREE_CODE (decl) == TYPE_DECL) + token->id_kind = C_ID_TYPENAME; + } + else if (c_dialect_objc ()) + { + tree objc_interface_decl = objc_is_class_name (token->value); + /* Objective-C class names are in the same namespace as + variables and typedefs, and hence are shadowed by local + declarations. */ + if (objc_interface_decl) + { + token->value = objc_interface_decl; + token->id_kind = C_ID_CLASSNAME; + } + } + } + } +} + /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition is accepted; otherwise (old-style parameter declarations) only other @@ -3021,6 +3058,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, function definitions either. */ int save_debug_nonbind_markers_p = debug_nonbind_markers_p; debug_nonbind_markers_p = 0; + c_parser_maybe_reclassify_token (parser); while (c_parser_next_token_is_not (parser, CPP_EOF) && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) c_parser_declaration_or_fndef (parser, false, false, false, @@ -8359,43 +8397,6 @@ c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo, return c_end_compound_stmt (body_loc, block, flag_isoc99); } -/* 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. */ - -static void -c_parser_maybe_reclassify_token (c_parser *parser) -{ - if (c_parser_next_token_is (parser, CPP_NAME)) - { - c_token *token = c_parser_peek_token (parser); - - if (token->id_kind != C_ID_CLASSNAME) - { - tree decl = lookup_name (token->value); - - token->id_kind = C_ID_ID; - if (decl) - { - if (TREE_CODE (decl) == TYPE_DECL) - token->id_kind = C_ID_TYPENAME; - } - else if (c_dialect_objc ()) - { - tree objc_interface_decl = objc_is_class_name (token->value); - /* Objective-C class names are in the same namespace as - variables and typedefs, and hence are shadowed by local - declarations. */ - if (objc_interface_decl) - { - token->value = objc_interface_decl; - token->id_kind = C_ID_CLASSNAME; - } - } - } - } -} - /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4). if-statement: |