From: Jakub Jelinek Date: Wed, 15 Jan 2025 16:04:31 +0000 (+0100) Subject: c++: Implement mangling of RAW_DATA_CST [PR118278] X-Git-Tag: basepoints/gcc-16~2636 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d9d583484006a75bc3ed3b3badb585f3a0bb546;p=thirdparty%2Fgcc.git 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 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 --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 struct X { }; + +typedef X 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 struct Y { }; + +typedef Y Tca; +void g (Tca) { } +// { dg-final { scan-assembler "_Z1g1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA144_h(?:Lh101ELh102ELh103ELh104ELh105ELh106ELh255ELh254ELh253ELh252ELh251ELh0ELh1ELh2ELh3ELh4E){8}Lh101ELh102EEEEE" } } + +typedef Y 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 struct Z { }; + +typedef Z 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 struct Y { }; + +typedef Y Tca; +void g (Tca) { } +// { dg-final { scan-assembler "_Z1g1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA128_h(?:Lh\[0-9]*E){128}EEEE" } } + +typedef Y Tcs; +void h (Tcs) { } +// { dg-final { scan-assembler "_Z1h1YIXtl1CtlA5_hLh1ELh2EEtlS1_EtlA128_h(?:Lh\[0-9]*E){128}EEEE" } }