[gcc(refs/users/aoliva/heads/testme)] d: Fix no NRVO when returning an array of a non-POD struct

Alexandre Oliva aoliva@gcc.gnu.org
Thu Sep 3 16:00:16 GMT 2020


https://gcc.gnu.org/g:312ad889e99ff9458c01518325775e75ab57f272

commit 312ad889e99ff9458c01518325775e75ab57f272
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Tue Aug 25 00:39:17 2020 +0200

    d: Fix no NRVO when returning an array of a non-POD struct
    
    TREE_ADDRESSABLE was not propagated from the RECORD_TYPE to the ARRAY_TYPE, so
    NRVO code generation was not being triggered.
    
    gcc/d/ChangeLog:
    
            PR d/96157
            * d-codegen.cc (d_build_call): Handle TREE_ADDRESSABLE static arrays.
            * types.cc (make_array_type): Propagate TREE_ADDRESSABLE from base
            type to static array.
    
    gcc/testsuite/ChangeLog:
    
            PR d/96157
            * gdc.dg/pr96157a.d: New test.
            * gdc.dg/pr96157b.d: New test.

Diff:
---
 gcc/d/d-codegen.cc              |  4 ++--
 gcc/d/types.cc                  |  7 +++++--
 gcc/testsuite/gdc.dg/pr96157a.d | 24 +++++++++++++++++++++
 gcc/testsuite/gdc.dg/pr96157b.d | 46 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 73a6a340ccf..6a7ecc50645 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1987,11 +1987,11 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
 	      targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
 	    }
 
-	  /* Parameter is a struct passed by invisible reference.  */
+	  /* Parameter is a struct or array passed by invisible reference.  */
 	  if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
 	    {
 	      Type *t = arg->type->toBasetype ();
-	      StructDeclaration *sd = t->isTypeStruct ()->sym;
+	      StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
 
 	      /* Nested structs also have ADDRESSABLE set, but if the type has
 		 neither a copy constructor nor a destructor available, then we
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 0d05e4d82b3..994d0b9195b 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -186,8 +186,11 @@ make_array_type (Type *type, unsigned HOST_WIDE_INT size)
       return t;
     }
 
-  return build_array_type (build_ctype (type),
-			   build_index_type (size_int (size - 1)));
+  tree t = build_array_type (build_ctype (type),
+			     build_index_type (size_int (size - 1)));
+  /* Propagate TREE_ADDRESSABLE to the static array type.  */
+  TREE_ADDRESSABLE (t) = TREE_ADDRESSABLE (TREE_TYPE (t));
+  return t;
 }
 
 /* Builds a record type whose name is NAME.  NFIELDS is the number of fields,
diff --git a/gcc/testsuite/gdc.dg/pr96157a.d b/gcc/testsuite/gdc.dg/pr96157a.d
new file mode 100644
index 00000000000..11df19ea700
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr96157a.d
@@ -0,0 +1,24 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96157
+// { dg-do run { target native } }
+// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
+
+struct S
+{
+    @disable this(this); // triggers nrvo
+    int v;
+}
+
+__gshared void* p;
+
+S[1000] foo() nothrow
+{
+    typeof(return) d;
+    p = &d;
+    return d;
+}
+
+void main()
+{
+    auto d = foo();
+    assert(p == &d);
+}
diff --git a/gcc/testsuite/gdc.dg/pr96157b.d b/gcc/testsuite/gdc.dg/pr96157b.d
new file mode 100644
index 00000000000..40a7e0ba787
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr96157b.d
@@ -0,0 +1,46 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96157
+// { dg-options "-fno-moduleinfo -fno-rtti" }
+// { dg-do compile }
+
+int[] testYearsBC;
+
+struct FilterResult
+{
+    int[] input;
+    bool primed;
+
+    this(int[] r)
+    {
+        this.input = r;
+    }
+
+    int front()
+    {
+        return input[0];
+    }
+};
+
+FilterResult filter(int[] range)
+{
+    return FilterResult(range);
+}
+
+int[] chain(int[] rs)
+{
+    return rs;
+}
+
+struct SysTime
+{
+    this(int);
+}
+
+void test()
+{
+    while (1)
+    {
+        FilterResult val = filter(chain(testYearsBC));
+        int year = val.front();
+        SysTime(0);
+    }
+}


More information about the Gcc-cvs mailing list