https://gcc.gnu.org/g:80e1dac3849b134ebd5e0151e9c9e4b8b091de72

commit r15-8452-g80e1dac3849b134ebd5e0151e9c9e4b8b091de72
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Mar 19 05:15:00 2025 -0400

    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.

Diff:
---
 gcc/cp/mangle.cc                       | 13 ++++++++++---
 gcc/testsuite/g++.dg/abi/mangle-new1.C | 10 ++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index df61f2d573e7..9ca5cf6eecdc 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 000000000000..bb3ea9b2e96f
--- /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} } }

Reply via email to