diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-03-15 22:09:24 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-03-15 22:09:24 +0100 |
commit | ffc8b52f9a5e73ad375be213ddcb1a8371dc328b (patch) | |
tree | 03b47a89783a193a850fb2dbf9da6a016f76794d | |
parent | 724ad4a31b5655ebe8b8ca5ddf7db388231ee08b (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/calls.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr79085.C | 24 |
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 ()); +} |