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.
(cherry picked from commit
80e1dac3849b134ebd5e0151e9c9e4b8b091de72)
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;
}
}
else
{
+ gcc_checking_assert (TREE_CODE (max) == MINUS_EXPR
+ && integer_onep (TREE_OPERAND (max, 1)));
max = TREE_OPERAND (max, 0);
write_expression (max);
}
--- /dev/null
+// 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} } }