Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

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                       | 13 ++++++++++---
 gcc/testsuite/g++.dg/abi/mangle-new1.C | 10 ++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/abi/mangle-new1.C

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index df61f2d573e..9ca5cf6eecd 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 00000000000..bb3ea9b2e96
--- /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} } }

base-commit: e3b3290f7330a81176d3d5d7c77623cd6c4bc70c
-- 
2.48.1

Reply via email to