aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.cc
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2022-10-14 02:18:45 +0000
committerJoseph Myers <joseph@codesourcery.com>2022-10-14 02:18:45 +0000
commit18981635127c6701733dc052aa054e569271b733 (patch)
treeb4195c597f07b1ad29a276cfdc7edaa60fb21972 /gcc/c/c-decl.cc
parent621a911d336279d21e1e857cfead09af1c61df39 (diff)
downloadgcc-18981635127c6701733dc052aa054e569271b733.zip
gcc-18981635127c6701733dc052aa054e569271b733.tar.gz
gcc-18981635127c6701733dc052aa054e569271b733.tar.bz2
c: C2x storage class specifiers in compound literals
Implement the C2x feature of storage class specifiers in compound literals. Such storage class specifiers (static, register or thread_local; also constexpr, but we don't yet have C2x constexpr support implemented) can be used before the type name (not mixed with type specifiers, unlike in declarations) and have the same semantics and constraints as for declarations of named objects. Also allow GNU __thread to be used, given that thread_local can be. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ * 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. gcc/testsuite/ * gcc.dg/c11-complit-1.c, gcc.dg/c11-complit-2.c, gcc.dg/c11-complit-3.c, gcc.dg/c2x-complit-2.c, gcc.dg/c2x-complit-3.c, gcc.dg/c2x-complit-4.c, gcc.dg/c2x-complit-5.c, gcc.dg/c2x-complit-6.c, gcc.dg/c2x-complit-7.c, gcc.dg/c90-complit-2.c, gcc.dg/gnu2x-complit-1.c, gcc.dg/gnu2x-complit-2.c: New tests.
Diffstat (limited to 'gcc/c/c-decl.cc')
-rw-r--r--gcc/c/c-decl.cc33
1 files changed, 30 insertions, 3 deletions
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)
{