https://gcc.gnu.org/g:8d9d583484006a75bc3ed3b3badb585f3a0bb546

commit r15-6917-g8d9d583484006a75bc3ed3b3badb585f3a0bb546
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Jan 15 17:04:31 2025 +0100

    c++: Implement mangling of RAW_DATA_CST [PR118278]
    
    As the following testcases show (mangle80.C only after reversion of the
    temporary reversion of C++ large array speedup commit), RAW_DATA_CST can
    be seen during mangling of some templates and we ICE because
    the mangler doesn't handle it.
    
    The following patch handles it and mangles it the same as a sequence of
    INTEGER_CSTs that were used previously instead.
    The only slight complication is that if ce->value is the last nonzero
    element, we need to skip the zeros at the end of RAW_DATA_CST.
    
    2025-01-03  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/118278
            * mangle.cc (write_expression): Handle RAW_DATA_CST.
    
            * g++.dg/abi/mangle80.C: New test.
            * g++.dg/cpp/embed-19.C: New test.

Diff:
---
 gcc/cp/mangle.cc                    | 37 ++++++++++++++++++--
 gcc/testsuite/g++.dg/abi/mangle80.C | 67 +++++++++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp/embed-19.C | 18 ++++++++++
 3 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 170dafd52c17..114e4a0d7c59 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -3748,8 +3748,41 @@ write_expression (tree expr)
                    unsigned reps = 1;
                    if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
                      reps = range_expr_nelts (ce->index);
-                   for (unsigned j = 0; j < reps; ++j)
-                     write_expression (ce->value);
+                   if (TREE_CODE (ce->value) == RAW_DATA_CST)
+                     {
+                       gcc_assert (reps == 1);
+                       unsigned int len = RAW_DATA_LENGTH (ce->value);
+                       /* If this is the last non-zero element, skip
+                          zeros at the end.  */
+                       if (i == last_nonzero)
+                         while (len)
+                           {
+                             if (RAW_DATA_POINTER (ce->value)[len - 1])
+                               break;
+                             --len;
+                           }
+                       tree valtype = TREE_TYPE (ce->value);
+                       for (unsigned int i = 0; i < len; ++i)
+                         {
+                           write_char ('L');
+                           write_type (valtype);
+                           unsigned HOST_WIDE_INT v;
+                           if (!TYPE_UNSIGNED (valtype)
+                               && TYPE_PRECISION (valtype) == BITS_PER_UNIT
+                               && RAW_DATA_SCHAR_ELT (ce->value, i) < 0)
+                             {
+                               write_char ('n');
+                               v = -RAW_DATA_SCHAR_ELT (ce->value, i);
+                             }
+                           else
+                             v = RAW_DATA_UCHAR_ELT (ce->value, i);
+                           write_unsigned_number (v);
+                           write_char ('E');
+                         }
+                     }
+                   else
+                     for (unsigned j = 0; j < reps; ++j)
+                       write_expression (ce->value);
                  }
            }
          else
diff --git a/gcc/testsuite/g++.dg/abi/mangle80.C 
b/gcc/testsuite/g++.dg/abi/mangle80.C
new file mode 100644
index 000000000000..e4f6934b431e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle80.C
@@ -0,0 +1,67 @@
+// PR c++/118278
+// Verify that class literals are mangled the same way regardless
+// of the underlying type.
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fabi-compat-version=0 }
+
+struct I { int a[5], b[5], c[144]; };
+template <I> struct X { };
+
+typedef X<I{ {1,2}, {}, {
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }> Ti;
+void f (Ti) { }
+// { dg-final { scan-assembler 
"_Z1f1XIXtl1ItlA5_iLi1ELi2EEtlS1_EtlA144_i(?:Li101ELi102ELi103ELi104ELi105ELi106ELi255ELi254ELi253ELi252ELi251ELi0ELi1ELi2ELi3ELi4E){8}Li101ELi102EEEEE"
 } }
+
+struct C { unsigned char a[5], b[5], c[144]; };
+template <C> struct Y { };
+
+typedef Y<C{ {1,2}, {}, {
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }> Tca;
+void g (Tca) { }
+// { dg-final { scan-assembler 
"_Z1g1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA144_h(?:Lh101ELh102ELh103ELh104ELh105ELh106ELh255ELh254ELh253ELh252ELh251ELh0ELh1ELh2ELh3ELh4E){8}Lh101ELh102EEEEE"
 } }
+
+typedef Y<C{ "\1\2", "", {
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,103,104,105,106,255,254,253,252,251,0,1,2,3,4,
+101,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }> Tcs;
+void h (Tcs) { }
+// { dg-final { scan-assembler 
"_Z1h1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA144_h(?:Lh101ELh102ELh103ELh104ELh105ELh106ELh255ELh254ELh253ELh252ELh251ELh0ELh1ELh2ELh3ELh4E){8}Lh101ELh102EEEEE"
 } }
+
+struct S { signed char a[5], b[5], c[144]; };
+template <S> struct Z { };
+
+typedef Z<S{ {1,2}, {}, {
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,103,104,105,106,95,94,93,92,91,0,1,2,3,4,
+101,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }> Tsc;
+
+void i (Tsc) { }
+// { dg-final { scan-assembler 
"_Z1i1ZIXtl1StlA5_aLa1ELa2EEtlS1_EtlA144_a(?:La101ELa102ELa103ELa104ELa105ELa106ELa95ELa94ELa93ELa92ELa91ELa0ELa1ELa2ELa3ELa4E){8}La101ELa102EEEEE"
 } }
diff --git a/gcc/testsuite/g++.dg/cpp/embed-19.C 
b/gcc/testsuite/g++.dg/cpp/embed-19.C
new file mode 100644
index 000000000000..bd7b9fa0e496
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp/embed-19.C
@@ -0,0 +1,18 @@
+// PR c++/118278
+// { dg-do compile { target c++20 } }
+// { dg-options "-fabi-compat-version=0" }
+
+struct C { unsigned char a[5], b[5], c[128]; };
+template <C> struct Y { };
+
+typedef Y<C{ {1,2}, {}, {
+#embed __FILE__ __limit__ (128)
+} }> Tca;
+void g (Tca) { }
+// { dg-final { scan-assembler 
"_Z1g1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA128_h(?:Lh\[0-9]*E){128}EEEE" } }
+
+typedef Y<C{ "\1\2", "", {
+#embed __FILE__ __limit__ (128)
+} }> Tcs;
+void h (Tcs) { }
+// { dg-final { scan-assembler 
"_Z1h1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA128_h(?:Lh\[0-9]*E){128}EEEE" } }

Reply via email to