diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/expr.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr96194.C | 21 |
2 files changed, 24 insertions, 1 deletions
@@ -8382,7 +8382,9 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM /* Also make a temporary if the store is to volatile memory, to avoid individual accesses to aggregate members. */ - || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))) + || (GET_CODE (target) == MEM + && MEM_VOLATILE_P (target) + && !TREE_ADDRESSABLE (TREE_TYPE (exp)))) { if (avoid_temp_mem) return NULL_RTX; diff --git a/gcc/testsuite/g++.dg/opt/pr96194.C b/gcc/testsuite/g++.dg/opt/pr96194.C new file mode 100644 index 0000000..749be2a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr96194.C @@ -0,0 +1,21 @@ +// PR middle-end/96194 +// { dg-do compile } +// { dg-options "-O2" } + +#include <new> + +struct A { ~A (); }; +struct B : A { float e[64]; }; + +B * +foo () +{ + return new ((void *) 0) B (); +} + +B * +bar (void *x, bool y) +{ + void *p = y ? x : (void *) 0; + return new (p) B (); +} |