I ran the tests for g++.dg/init thus far. Does this patch make sense? 2017-03-20 Ville Voutilainen <ville.voutilai...@gmail.com>
gcc/ PR c++/35878 * cp/init.c (build_new_1): Don't do a null check for a placement new. testsuite/ PR c++/35878 * testsuite/g++.dg/init/placement6.C: New.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8bfcbde..d3ac96f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3450,7 +3450,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, rval = TARGET_EXPR_INITIAL (alloc_expr); else { - if (check_new) + if (check_new && (nothrow || !placement_allocation_fn_p)) { tree ifexp = cp_build_binary_op (input_location, NE_EXPR, alloc_node, diff --git a/gcc/testsuite/g++.dg/init/placement6.C b/gcc/testsuite/g++.dg/init/placement6.C new file mode 100644 index 0000000..5e43812 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/placement6.C @@ -0,0 +1,21 @@ +// { dg-options "-O2 --std=gnu++11" } +// { dg-do compile } +// { dg-final { scan-assembler-not "test rdi, rdi" { target i?86-*-* x86_64-*-* } } } +#include <new> +#include <utility> + +struct s1{ + int a; + int b; + int c; +}; + +void f1 (s1 * v, s1&& s) +{ + new (v) s1(std::move(s)); +} + +void f2 (s1 * v, s1&& s) +{ + *v = std::move(s); +}