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
