aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-03-19 05:15:00 -0400
committerJason Merrill <jason@redhat.com>2025-03-19 17:58:23 -0400
commit80e1dac3849b134ebd5e0151e9c9e4b8b091de72 (patch)
tree37343b646cff006767d99761f6905ad26a919d62
parente3b3290f7330a81176d3d5d7c77623cd6c4bc70c (diff)
downloadgcc-80e1dac3849b134ebd5e0151e9c9e4b8b091de72.zip
gcc-80e1dac3849b134ebd5e0151e9c9e4b8b091de72.tar.gz
gcc-80e1dac3849b134ebd5e0151e9c9e4b8b091de72.tar.bz2
c++: mangling of array new [PR119316]
Because we build an array type to represent an array new, we hit a VLA error in compute_array_index_type for a variable length array new. To avoid this, let's build the MINUS_EXPR and index type directly. I also noticed that the non-constant case in write_array_type was assuming MINUS_EXPR without verifying it, so I added a checking_assert. I also noticed that Clang doesn't mangle the length of an array new at all, so I opened https://github.com/itanium-cxx-abi/cxx-abi/issues/199 to clarify this. PR c++/119316 gcc/cp/ChangeLog: * mangle.cc (write_expression) [NEW_EXPR]: Avoid using compute_array_index_type. (write_array_type): Add checking_assert. gcc/testsuite/ChangeLog: * g++.dg/abi/mangle-new1.C: New test.
-rw-r--r--gcc/cp/mangle.cc13
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle-new1.C10
2 files changed, 20 insertions, 3 deletions
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index df61f2d..9ca5cf6 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -3642,10 +3642,15 @@ write_expression (tree expr)
if (nelts)
{
- tree domain;
++processing_template_decl;
- domain = compute_array_index_type (NULL_TREE, nelts,
- tf_warning_or_error);
+ /* Avoid compute_array_index_type complaints about
+ non-constant nelts. */
+ tree max = cp_build_binary_op (input_location, MINUS_EXPR,
+ fold_convert (sizetype, nelts),
+ size_one_node,
+ tf_warning_or_error);
+ max = maybe_constant_value (max);
+ tree domain = build_index_type (max);
type = build_cplus_array_type (type, domain);
--processing_template_decl;
}
@@ -4242,6 +4247,8 @@ write_array_type (const tree type)
}
else
{
+ gcc_checking_assert (TREE_CODE (max) == MINUS_EXPR
+ && integer_onep (TREE_OPERAND (max, 1)));
max = TREE_OPERAND (max, 0);
write_expression (max);
}
diff --git a/gcc/testsuite/g++.dg/abi/mangle-new1.C b/gcc/testsuite/g++.dg/abi/mangle-new1.C
new file mode 100644
index 0000000..bb3ea9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle-new1.C
@@ -0,0 +1,10 @@
+// PR c++/119316
+// { dg-do compile { target c++11 } }
+
+template <unsigned> struct A { };
+template<typename T>
+auto foo(unsigned n) -> A<sizeof(new T[n])>
+{ return {}; }
+int main() { foo<int>(5); }
+
+// { dg-final { scan-assembler {_Z3fooIiE1AIXszna_Afp__T_EEEj} } }