On Tue, Oct 21, 2025 at 07:25:40PM +0200, Jakub Jelinek wrote: > 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?
LGTM. > 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 > Marek
