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

Reply via email to