aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-03-15 22:09:24 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-03-15 22:09:24 +0100
commitffc8b52f9a5e73ad375be213ddcb1a8371dc328b (patch)
tree03b47a89783a193a850fb2dbf9da6a016f76794d
parent724ad4a31b5655ebe8b8ca5ddf7db388231ee08b (diff)
downloadgcc-ffc8b52f9a5e73ad375be213ddcb1a8371dc328b.zip
gcc-ffc8b52f9a5e73ad375be213ddcb1a8371dc328b.tar.gz
gcc-ffc8b52f9a5e73ad375be213ddcb1a8371dc328b.tar.bz2
re PR c++/79085 (ICE with placement new to unaligned location)
PR c++/79085 * calls.c (expand_call): For TREE_ADDRESSABLE rettype ignore alignment check and use address of target always. * g++.dg/opt/pr79085.C: New test. From-SVN: r258574
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/calls.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/pr79085.C24
4 files changed, 43 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1d0ab4e..2fe4a21 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/79085
+ * calls.c (expand_call): For TREE_ADDRESSABLE rettype ignore alignment
+ check and use address of target always.
+
2018-03-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/84574
diff --git a/gcc/calls.c b/gcc/calls.c
index 19c95b8..4dcfef7 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3422,9 +3422,14 @@ expand_call (tree exp, rtx target, int ignore)
if (CALL_EXPR_RETURN_SLOT_OPT (exp)
&& target
&& MEM_P (target)
- && !(MEM_ALIGN (target) < TYPE_ALIGN (rettype)
- && targetm.slow_unaligned_access (TYPE_MODE (rettype),
- MEM_ALIGN (target))))
+ /* If rettype is addressable, we may not create a temporary.
+ If target is properly aligned at runtime and the compiler
+ just doesn't know about it, it will work fine, otherwise it
+ will be UB. */
+ && (TREE_ADDRESSABLE (rettype)
+ || !(MEM_ALIGN (target) < TYPE_ALIGN (rettype)
+ && targetm.slow_unaligned_access (TYPE_MODE (rettype),
+ MEM_ALIGN (target)))))
structure_value_addr = XEXP (target, 0);
else
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4b42ab7..ca6618f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/79085
+ * g++.dg/opt/pr79085.C: New test.
+
2018-03-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/84574
diff --git a/gcc/testsuite/g++.dg/opt/pr79085.C b/gcc/testsuite/g++.dg/opt/pr79085.C
new file mode 100644
index 0000000..1d75d6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr79085.C
@@ -0,0 +1,24 @@
+// PR c++/79085
+// { dg-do compile }
+// { dg-options "-Os" }
+// { dg-additional-options "-mstrict-align" { target { aarch64*-*-* powerpc*-*-linux* powerpc*-*-elf* } } }
+
+void *operator new (__SIZE_TYPE__, void *p) { return p; }
+
+struct S
+{
+ S ();
+ S (const S &);
+ ~S (void);
+ int i;
+};
+
+S foo ();
+
+static char buf [sizeof (S) + 1];
+
+S *
+bar ()
+{
+ return new (buf + 1) S (foo ());
+}