diff options
author | Martin Liska <mliska@suse.cz> | 2022-10-15 15:32:39 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-10-15 15:32:39 +0200 |
commit | 2c92cfe87d2bb8aa0eb78f3932fca16699cb35c9 (patch) | |
tree | b118381a0a883a762ddd56c0e91608d937ee8bdf /gcc/c/c-parser.cc | |
parent | bd21c04269deded2c7476ceca1100a26f28ea526 (diff) | |
parent | baeec7cc83b19b46d1c73523f06efa7ea2b30390 (diff) | |
download | gcc-2c92cfe87d2bb8aa0eb78f3932fca16699cb35c9.zip gcc-2c92cfe87d2bb8aa0eb78f3932fca16699cb35c9.tar.gz gcc-2c92cfe87d2bb8aa0eb78f3932fca16699cb35c9.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/c/c-parser.cc')
-rw-r--r-- | gcc/c/c-parser.cc | 91 |
1 files changed, 81 insertions, 10 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 89e0587..602e023 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -666,6 +666,30 @@ c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) return false; } +/* Return true if TOKEN, after an open parenthesis, can start a + compound literal (either a storage class specifier allowed in that + context, or a type name), false otherwise. */ +static bool +c_token_starts_compound_literal (c_token *token) +{ + switch (token->type) + { + case CPP_KEYWORD: + switch (token->keyword) + { + case RID_REGISTER: + case RID_STATIC: + case RID_THREAD: + return true; + default: + break; + } + /* Fall through. */ + default: + return c_token_starts_typename (token); + } +} + /* Return true if TOKEN is a type qualifier, false otherwise. */ static bool c_token_is_qualifier (c_token *token) @@ -1563,6 +1587,7 @@ static struct c_expr c_parser_sizeof_expression (c_parser *); static struct c_expr c_parser_alignof_expression (c_parser *); static struct c_expr c_parser_postfix_expression (c_parser *); static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, + struct c_declspecs *, struct c_type_name *, location_t); static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, @@ -8237,6 +8262,34 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, #undef POP } +/* Parse any storage class specifiers after an open parenthesis in a + context where a compound literal is permitted. */ + +static struct c_declspecs * +c_parser_compound_literal_scspecs (c_parser *parser) +{ + bool seen_scspec = false; + struct c_declspecs *specs = build_null_declspecs (); + while (c_parser_next_token_is (parser, CPP_KEYWORD)) + { + switch (c_parser_peek_token (parser)->keyword) + { + case RID_REGISTER: + case RID_STATIC: + case RID_THREAD: + seen_scspec = true; + declspecs_add_scspec (c_parser_peek_token (parser)->location, + specs, c_parser_peek_token (parser)->value); + c_parser_consume_token (parser); + break; + default: + goto out; + } + } + out: + return seen_scspec ? specs : NULL; +} + /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER is not NULL then it is an Objective-C message expression which is the primary-expression starting the expression as an initializer. @@ -8260,13 +8313,15 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) an unary expression. Full detection of unknown typenames here would require a 3-token lookahead. */ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) - && c_token_starts_typename (c_parser_peek_2nd_token (parser))) + && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser))) { + struct c_declspecs *scspecs; struct c_type_name *type_name; struct c_expr ret; struct c_expr expr; matching_parens parens; parens.consume_open (parser); + scspecs = c_parser_compound_literal_scspecs (parser); type_name = c_parser_type_name (parser, true); parens.skip_until_found_close (parser); if (type_name == NULL) @@ -8281,8 +8336,11 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) used_types_insert (type_name->specs->type); if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - return c_parser_postfix_expression_after_paren_type (parser, type_name, + return c_parser_postfix_expression_after_paren_type (parser, scspecs, + type_name, cast_loc); + if (scspecs) + error_at (cast_loc, "storage class specifier in cast"); if (type_name->specs->alignas_p) error_at (type_name->specs->locations[cdw_alignas], "alignment specified for type name in cast"); @@ -8485,14 +8543,16 @@ c_parser_sizeof_expression (c_parser *parser) c_inhibit_evaluation_warnings++; in_sizeof++; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) - && c_token_starts_typename (c_parser_peek_2nd_token (parser))) + && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser))) { /* Either sizeof ( type-name ) or sizeof unary-expression starting with a compound literal. */ + struct c_declspecs *scspecs; struct c_type_name *type_name; matching_parens parens; parens.consume_open (parser); expr_loc = c_parser_peek_token (parser)->location; + scspecs = c_parser_compound_literal_scspecs (parser); type_name = c_parser_type_name (parser, true); parens.skip_until_found_close (parser); finish = parser->tokens_buf[0].location; @@ -8508,13 +8568,15 @@ c_parser_sizeof_expression (c_parser *parser) } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { - expr = c_parser_postfix_expression_after_paren_type (parser, + expr = c_parser_postfix_expression_after_paren_type (parser, scspecs, type_name, expr_loc); finish = expr.get_finish (); goto sizeof_expr; } /* sizeof ( type-name ). */ + if (scspecs) + error_at (expr_loc, "storage class specifier in %<sizeof%>"); if (type_name->specs->alignas_p) error_at (type_name->specs->locations[cdw_alignas], "alignment specified for type name in %<sizeof%>"); @@ -8572,16 +8634,18 @@ c_parser_alignof_expression (c_parser *parser) c_inhibit_evaluation_warnings++; in_alignof++; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) - && c_token_starts_typename (c_parser_peek_2nd_token (parser))) + && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser))) { /* Either __alignof__ ( type-name ) or __alignof__ unary-expression starting with a compound literal. */ location_t loc; + struct c_declspecs *scspecs; struct c_type_name *type_name; struct c_expr ret; matching_parens parens; parens.consume_open (parser); loc = c_parser_peek_token (parser)->location; + scspecs = c_parser_compound_literal_scspecs (parser); type_name = c_parser_type_name (parser, true); end_loc = c_parser_peek_token (parser)->location; parens.skip_until_found_close (parser); @@ -8597,12 +8661,14 @@ c_parser_alignof_expression (c_parser *parser) } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { - expr = c_parser_postfix_expression_after_paren_type (parser, + expr = c_parser_postfix_expression_after_paren_type (parser, scspecs, type_name, loc); goto alignof_expr; } /* alignof ( type-name ). */ + if (scspecs) + error_at (loc, "storage class specifier in %qE", alignof_spelling); if (type_name->specs->alignas_p) error_at (type_name->specs->locations[cdw_alignas], "alignment specified for type name in %qE", @@ -9140,8 +9206,8 @@ c_parser_predefined_identifier (c_parser *parser) postfix-expression -> identifier postfix-expression ++ postfix-expression -- - ( type-name ) { initializer-list } - ( type-name ) { initializer-list , } + ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] } + ( storage-class-specifiers[opt] type-name ) { initializer-list , } argument-expression-list: argument-expression @@ -10483,6 +10549,7 @@ c_parser_postfix_expression (c_parser *parser) static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *parser, + struct c_declspecs *scspecs, struct c_type_name *type_name, location_t type_loc) { @@ -10515,7 +10582,11 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, type = error_mark_node; } - pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals"); + if (!pedwarn_c90 (start_loc, OPT_Wpedantic, + "ISO C90 forbids compound literals") && scspecs) + pedwarn_c11 (start_loc, OPT_Wpedantic, + "ISO C forbids storage class specifiers in compound literals " + "before C2X"); non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) ? CONSTRUCTOR_NON_CONST (init.value) : init.original_code == C_MAYBE_CONST_EXPR); @@ -10534,7 +10605,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, } } expr.value = build_compound_literal (start_loc, type, init.value, non_const, - alignas_align); + alignas_align, scspecs); set_c_expr_source_range (&expr, init.src_range); expr.m_decimal = 0; expr.original_code = ERROR_MARK; |