]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Check for modifiable static compound literals in inline definitions
authorJoseph Myers <joseph@codesourcery.com>
Mon, 9 Jan 2023 21:56:34 +0000 (21:56 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Mon, 9 Jan 2023 21:56:34 +0000 (21:56 +0000)
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.

gcc/c/c-decl.cc
gcc/testsuite/gcc.dg/c2x-complit-8.c [new file with mode: 0644]

index e47ca6718b3ea004e8437fbc5a93ae4d663dda82..d76ffb3380d88397dcef3baf330e53f8812218f7 100644 (file)
@@ -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 (file)
index 0000000..fb614ab
--- /dev/null
@@ -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 ();