summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2021-01-22 16:29:09 +0800
committerKito Cheng <kito.cheng@sifive.com>2021-02-02 16:56:06 +0800
commitbc7c2b34c34f21ea58198ba58a48eb065bdda25d (patch)
tree1e790669a1a090b73234f5eae23f5b1494af6baa
parent250fd9fb118a6897e6c824a0faac634861ea7716 (diff)
downloadgcc-bc7c2b34c34f21ea58198ba58a48eb065bdda25d.tar.gz
PR target/98743: Fix ICE in convert_move for RISC-V
- 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.
-rw-r--r--gcc/expr.c1
-rw-r--r--gcc/testsuite/g++.dg/opt/pr98743.C27
2 files changed, 28 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 04ef5ad114d..86dc1b6c973 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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
index 00000000000..41f476fbe8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr98743.C
@@ -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;
+}