diff mbox series

[committed] c: Check for modifiable static compound literals in inline definitions

Message ID 572c6924-616-997f-c3c1-684f3bf37b59@codesourcery.com
State New
Headers show
Series [committed] c: Check for modifiable static compound literals in inline definitions | expand

Commit Message

Joseph Myers Jan. 9, 2023, 9:57 p.m. UTC
The C rule against modifiable objects with static storage duration in
inline definitions should apply to compound literals (using the C2x
feature of storage-class specifiers for compound literals) just as to
variables.  Add a call to record_inline_static for compound literals
to make sure this case is detected.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/c/
	* c-decl.cc (build_compound_literal): Call record_inline_static.

gcc/testsuite/
	* gcc.dg/c2x-complit-8.c: New test.
diff mbox series

Patch

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index e47ca6718b3..d76ffb3380d 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6260,6 +6260,13 @@  build_compound_literal (location_t loc, tree type, tree init, bool non_const,
       DECL_USER_ALIGN (decl) = 1;
     }
   store_init_value (loc, decl, init, NULL_TREE);
+  if (current_scope != file_scope
+      && TREE_STATIC (decl)
+      && !TREE_READONLY (decl)
+      && DECL_DECLARED_INLINE_P (current_function_decl)
+      && DECL_EXTERNAL (current_function_decl))
+    record_inline_static (input_location, current_function_decl,
+			  decl, csi_modifiable);
 
   if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
     {
diff --git a/gcc/testsuite/gcc.dg/c2x-complit-8.c b/gcc/testsuite/gcc.dg/c2x-complit-8.c
new file mode 100644
index 00000000000..fb614ab7802
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-complit-8.c
@@ -0,0 +1,70 @@ 
+/* Test C2x storage class specifiers in compound literals: inline function
+   constraints.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+inline void
+f1 ()
+{
+  (static int) { 123 }; /* { dg-error "static but declared in inline function 'f1' which is not static" } */
+  (static thread_local int) { 456 } ; /* { dg-error "static but declared in inline function 'f1' which is not static" } */
+  (int) { 789 };
+  (register int) { 1234 };
+}
+
+inline void
+f1e ()
+{
+  (static int) { 123 };
+  (static thread_local int) { 456 } ;
+}
+
+static inline void
+f1s ()
+{
+  (static int) { 123 };
+  (static thread_local int) { 456 } ;
+}
+
+inline void
+f2 ()
+{
+  (static const int) { 123 };
+  (static thread_local const int) { 456 };
+}
+
+inline void
+f2e ()
+{
+  (static const int) { 123 };
+  (static thread_local const int) { 456 };
+}
+
+static inline void
+f2s ()
+{
+  (static const int) { 123 };
+  (static thread_local const int) { 456 };
+}
+
+inline void
+f3 ()
+{
+  (static constexpr int) { 123 };
+}
+
+inline void
+f3e ()
+{
+  (static constexpr int) { 123 };
+}
+
+static inline void
+f3s ()
+{
+  (static constexpr int) { 123 };
+}
+
+extern void f1e ();
+extern void f2e ();
+extern void f3e ();