]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: mangling of array new [PR119316]
authorJason Merrill <jason@redhat.com>
Wed, 19 Mar 2025 09:15:00 +0000 (05:15 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 19 Mar 2025 21:58:23 +0000 (17:58 -0400)
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.

gcc/cp/mangle.cc
gcc/testsuite/g++.dg/abi/mangle-new1.C [new file with mode: 0644]

index df61f2d573e778849b902e7da8769463c12a01d1..9ca5cf6eecdcbcc10ed23bba3f43fb8c30a66d26 100644 (file)
@@ -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 (file)
index 0000000..bb3ea9b
--- /dev/null
@@ -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} } }