d: Force TYPE_MODE of classes and non-POD structs as BLKmode
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 22 Dec 2020 08:47:22 +0000 (09:47 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Wed, 23 Dec 2020 16:32:52 +0000 (17:32 +0100)
Without this being forced, the optimizer could still make decisions that
require objects of the non-POD types to need a temporary, which would
result in an ICE during the expand to RTL passes.

gcc/d/ChangeLog:

PR d/98427
* types.cc (TypeVisitor::visit (TypeStruct *)): Set TYPE_MODE of all
non-trivial types as BLKmode.
(TypeVisitor::visit (TypeClass *)): Likewise.

gcc/testsuite/ChangeLog:

PR d/98427
* gdc.dg/pr98427.d: New test.

gcc/d/types.cc
gcc/testsuite/gdc.dg/pr98427.d [new file with mode: 0644]

index 94aa1f6b9b31952bfb4b9f1fb26441ed388f5f8d..acb8c40952653a80ec7c7a97dc7658b95294189b 100644 (file)
@@ -964,7 +964,10 @@ public:
     if (!t->sym->isPOD ())
       {
        for (tree tv = t->ctype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))
-         TREE_ADDRESSABLE (tv) = 1;
+         {
+           TREE_ADDRESSABLE (tv) = 1;
+           SET_TYPE_MODE (tv, BLKmode);
+         }
       }
   }
 
@@ -999,7 +1002,10 @@ public:
 
     /* Classes only live in memory, so always set the TREE_ADDRESSABLE bit.  */
     for (tree tv = basetype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))
-      TREE_ADDRESSABLE (tv) = 1;
+      {
+       TREE_ADDRESSABLE (tv) = 1;
+       SET_TYPE_MODE (tv, BLKmode);
+      }
 
     /* Type is final, there are no derivations.  */
     if (t->sym->storage_class & STCfinal)
diff --git a/gcc/testsuite/gdc.dg/pr98427.d b/gcc/testsuite/gdc.dg/pr98427.d
new file mode 100644 (file)
index 0000000..225db8b
--- /dev/null
@@ -0,0 +1,23 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98427
+// { dg-do compile }
+// { dg-options "-O2 -fno-inline" }
+
+@trusted memoizeExpr()
+{
+    struct CodepointSet
+    {
+        struct CowArray
+        {
+            uint *ptr;
+        }
+
+        const CodepointSet binary(U)(U rhs)
+        {
+            return rhs;
+        }
+
+        CowArray array;
+    }
+
+    CodepointSet().binary(CodepointSet());
+}