Hi!

The following testcase is miscompiled, because a RAW_DATA_CST tree
node is shared by multiple CONSTRUCTORs and when the braced_list_to_string
function changes one to extend the RAW_DATA_CST over the single preceding
and single succeeding INTEGER_CST, it changes the RAW_DATA_CST in
the other CONSTRUCTOR where the elts around it are still present.

Fixed by tweaking a copy of it instead, like we handle it in other spots.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/15.3?

2025-10-21  Jakub Jelinek  <[email protected]>

        PR c++/122302
        * c-common.cc (braced_list_to_string): Call copy_node on RAW_DATA_CST
        before changing RAW_DATA_POINTER and RAW_DATA_LENGTH on it.

        * g++.dg/cpp0x/pr122302.C: New test.
        * g++.dg/cpp/embed-27.C: New test.

--- gcc/c-family/c-common.cc.jj 2025-10-09 22:41:19.698275596 +0200
+++ gcc/c-family/c-common.cc    2025-10-21 12:29:47.819594939 +0200
@@ -10296,6 +10296,7 @@ braced_list_to_string (tree type, tree c
                    j = i - start;
                  else
                    j -= start;
+                 value = copy_node (value);
                  RAW_DATA_POINTER (value) -= start;
                  RAW_DATA_LENGTH (value) += start + end;
                  i += end;
--- gcc/testsuite/g++.dg/cpp0x/pr122302.C.jj    2025-10-21 12:34:48.856419984 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/pr122302.C       2025-10-21 12:35:14.696061762 
+0200
@@ -0,0 +1,40 @@
+// PR c++/122302
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+
+struct A {
+  unsigned char a[130] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
16,
+                          1, 2 };
+};
+
+void
+foo ()
+{
+  A a;
+  for (int i = 0; i < 130; ++i)
+    if (a.a[i] != (i & 15) + 1)
+      __builtin_abort ();
+}
+
+void
+bar ()
+{
+  A a;
+  for (int i = 0; i < 130; ++i)
+    if (a.a[i] != (i & 15) + 1)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  bar ();
+}
--- gcc/testsuite/g++.dg/cpp/embed-27.C.jj      2025-10-21 12:35:39.939711804 
+0200
+++ gcc/testsuite/g++.dg/cpp/embed-27.C 2025-10-21 12:39:04.643873918 +0200
@@ -0,0 +1,38 @@
+// PR c++/122302
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+
+unsigned char b[] = {
+#embed "embed-27.C"
+};
+
+struct A {
+  unsigned char a[sizeof (b)] = { 
+#embed "embed-27.C"
+  };
+};
+
+void
+foo ()
+{
+  A a;
+  for (int i = 0; i < sizeof (b); ++i)
+    if (a.a[i] != b[i])
+      __builtin_abort ();
+}
+
+void
+bar ()
+{
+  A a;
+  for (int i = 0; i < sizeof (b); ++i)
+    if (a.a[i] != b[i])
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  bar ();
+}

        Jakub

Reply via email to