diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 33 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 91 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 8 |
5 files changed, 143 insertions, 14 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index a25e1b4..d28585b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,26 @@ +2022-10-14 Jakub Jelinek <jakub@redhat.com> + + * c-typeck.cc (convert_arguments): Don't promote __bf16 to + double. + +2022-10-14 Joseph Myers <joseph@codesourcery.com> + + * c-decl.cc (build_compound_literal): Add parameter scspecs. + Handle storage class specifiers. + * c-parser.cc (c_token_starts_compound_literal) + (c_parser_compound_literal_scspecs): New. + (c_parser_postfix_expression_after_paren_type): Add parameter + scspecs. Call pedwarn_c11 for use of storage class specifiers. + Update call to build_compound_literal. + (c_parser_cast_expression, c_parser_sizeof_expression) + (c_parser_alignof_expression): Handle storage class specifiers for + compound literals. Update calls to + c_parser_postfix_expression_after_paren_type. + (c_parser_postfix_expression): Update syntax comment. + * c-tree.h (build_compound_literal): Update prototype. + * c-typeck.cc (c_mark_addressable): Diagnose taking address of + register compound literal. + 2022-10-07 Qing Zhao <qing.zhao@oracle.com> * c-decl.cc (flexible_array_member_type_p): New function. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 193e268..a7571cc 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -6048,11 +6048,13 @@ mark_forward_parm_decls (void) literal. NON_CONST is true if the initializers contain something that cannot occur in a constant expression. If ALIGNAS_ALIGN is nonzero, it is the (valid) alignment for this compound literal, as specified - with _Alignas. */ + with _Alignas. SCSPECS are the storage class specifiers (C2x) from the + compound literal. */ tree build_compound_literal (location_t loc, tree type, tree init, bool non_const, - unsigned int alignas_align) + unsigned int alignas_align, + struct c_declspecs *scspecs) { /* We do not use start_decl here because we have a type, not a declarator; and do not use finish_decl because the decl should be stored inside @@ -6060,15 +6062,33 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const, tree decl; tree complit; tree stmt; + bool threadp = scspecs ? scspecs->thread_p : false; + enum c_storage_class storage_class = (scspecs + ? scspecs->storage_class + : csc_none); if (type == error_mark_node || init == error_mark_node) return error_mark_node; + if (current_scope == file_scope && storage_class == csc_register) + { + error_at (loc, "file-scope compound literal specifies %<register%>"); + storage_class = csc_none; + } + + if (current_scope != file_scope && threadp && storage_class == csc_none) + { + error_at (loc, "compound literal implicitly auto and declared %qs", + scspecs->thread_gnu_p ? "__thread" : "_Thread_local"); + threadp = false; + } + decl = build_decl (loc, VAR_DECL, NULL_TREE, type); DECL_EXTERNAL (decl) = 0; TREE_PUBLIC (decl) = 0; - TREE_STATIC (decl) = (current_scope == file_scope); + TREE_STATIC (decl) = (current_scope == file_scope + || storage_class == csc_static); DECL_CONTEXT (decl) = current_function_decl; TREE_USED (decl) = 1; DECL_READ_P (decl) = 1; @@ -6076,6 +6096,13 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const, DECL_IGNORED_P (decl) = 1; C_DECL_COMPOUND_LITERAL_P (decl) = 1; TREE_TYPE (decl) = type; + if (threadp) + set_decl_tls_model (decl, decl_default_tls_model (decl)); + if (storage_class == csc_register) + { + C_DECL_REGISTER (decl) = 1; + DECL_REGISTER (decl) = 1; + } c_apply_type_quals_to_decl (TYPE_QUALS (strip_array_types (type)), decl); if (alignas_align) { 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; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 46a3e8e..e7cdd2f 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -734,7 +734,7 @@ extern void set_init_label (location_t, tree, location_t, struct obstack *); extern void process_init_element (location_t, struct c_expr, bool, struct obstack *); extern tree build_compound_literal (location_t, tree, tree, bool, - unsigned int); + unsigned int, struct c_declspecs *); extern void check_compound_literal_type (location_t, struct c_type_name *); extern tree c_start_switch (location_t, location_t, tree, bool); extern void c_finish_switch (tree, tree); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index f919068..fdb96c2 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -3678,6 +3678,9 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, promote_float_arg = false; break; } + /* Don't promote __bf16 either. */ + if (TYPE_MAIN_VARIANT (valtype) == bfloat16_type_node) + promote_float_arg = false; } if (type != NULL_TREE) @@ -5114,6 +5117,11 @@ c_mark_addressable (tree exp, bool array_ref_p) break; case COMPOUND_LITERAL_EXPR: + if (C_DECL_REGISTER (COMPOUND_LITERAL_EXPR_DECL (x))) + { + error ("address of register compound literal requested"); + return false; + } TREE_ADDRESSABLE (x) = 1; TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1; return true; |