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.
--- gcc/cp/mangle.cc.jj 2025-01-02 11:47:10.534497080 +0100
+++ gcc/cp/mangle.cc 2025-01-02 16:48:06.688649097 +0100
@@ -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
--- gcc/testsuite/g++.dg/abi/mangle80.C.jj 2025-01-02 17:09:58.539575044
+0100
+++ gcc/testsuite/g++.dg/abi/mangle80.C 2025-01-02 17:22:45.457988243 +0100
@@ -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"
} }
--- gcc/testsuite/g++.dg/cpp/embed-19.C.jj 2025-01-02 17:02:08.181060996
+0100
+++ gcc/testsuite/g++.dg/cpp/embed-19.C 2025-01-02 17:06:23.430544485 +0100
@@ -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" } }
Jakub