PR target/98743: Fix ICE in convert_move for RISC-V
authorKito Cheng <kito.cheng@sifive.com>
Fri, 22 Jan 2021 08:29:09 +0000 (16:29 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Tue, 2 Feb 2021 08:56:06 +0000 (16:56 +0800)
 - Check `from` mode is not BLMmode before call store_expr, calling store_expr
   with BLKmode will cause ICE.

 - Verified with riscv64, x86_64 and aarch64, no introduce new regression.

Note: Those logic was introduced by 3e60ddeb8220ed388819bb3f14e8caa9309fd3c2,
      so I cc Jakub for reivew.

Changes for V2:

 - Checking mode of `from` rather than mode of `to`.
 - Verified on riscv64, x86_64 and aarch64 again.

gcc/ChangeLog:

PR target/98743
* expr.c: Check mode before calling store_expr.

gcc/testsuite/ChangeLog:

PR target/98743
* g++.dg/opt/pr98743.C: New.

gcc/expr.c
gcc/testsuite/g++.dg/opt/pr98743.C [new file with mode: 0644]

index 04ef5ad114d0662948c896cdbf58e67737b39c7e..86dc1b6c97349fd35126ecbaa217d6cc769c7d66 100644 (file)
@@ -5459,6 +5459,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
              /* If to_rtx is a promoted subreg, we need to zero or sign
                 extend the value afterwards.  */
              if (TREE_CODE (to) == MEM_REF
+                 && TYPE_MODE (TREE_TYPE (from)) != BLKmode
                  && !REF_REVERSE_STORAGE_ORDER (to)
                  && known_eq (bitpos, 0)
                  && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
diff --git a/gcc/testsuite/g++.dg/opt/pr98743.C b/gcc/testsuite/g++.dg/opt/pr98743.C
new file mode 100644 (file)
index 0000000..41f476f
--- /dev/null
@@ -0,0 +1,27 @@
+// Test for value-initialization via {}
+// { dg-do run { target c++11 } }
+/* { dg-options "-Og -fno-early-inlining -finline-small-functions -fpack-struct" */
+void * operator new (__SIZE_TYPE__, void *p) { return p; }
+void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
+
+// Empty base so A isn't an aggregate
+struct B {};
+struct A: B {
+  int i;
+};
+
+struct C: A {
+  C(): A{} {}
+};
+
+int main()
+{
+  int space = 42;
+  A* ap = new (&space) A{};
+  int space1[1] = { 42 };
+  A* a1p = new (space1) A[1]{};
+  if (ap->i != 0 ||
+      a1p[0].i != 0)
+    return 1;
+  return 0;
+}