Tested manually on Linux-X64, finishing testing with the full suite on Linux-PPC64.
I spent far too much time contemplating whether to add a compatibility switch for this, but -fcheck-new *is* such a compatibility switch. OK for trunk? 2017-11-10 Ville Voutilainen <ville.voutilai...@gmail.com> gcc/ Remove the null check from placement new in all modes * cp/init.c (build_new_1): Don't do a null check for a namespace-scope non-replaceable placement new in any mode unless -fcheck-new is provided. testsuite/ Remove the null check from placement new in all modes * g++.dg/init/pr35878_1.C: Adjust. * g++.dg/init/pr35878_4.C: New.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 9e6e3af..1fcd91d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2758,7 +2758,7 @@ malloc_alignment () static bool std_placement_new_fn_p (tree alloc_fn) { - if ((cxx_dialect > cxx14) && DECL_NAMESPACE_SCOPE_P (alloc_fn)) + if (DECL_NAMESPACE_SCOPE_P (alloc_fn)) { tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn))); if ((TREE_VALUE (first_arg) == ptr_type_node) diff --git a/gcc/testsuite/g++.dg/init/pr35878_1.C b/gcc/testsuite/g++.dg/init/pr35878_1.C index e2fc493..7fb3221 100644 --- a/gcc/testsuite/g++.dg/init/pr35878_1.C +++ b/gcc/testsuite/g++.dg/init/pr35878_1.C @@ -1,7 +1,7 @@ // PR c++/35878 // { dg-do compile } // { dg-options "-O2 -std=gnu++11 -fdump-tree-optimized" } -// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" } } +// { dg-final { scan-tree-dump-not "v_\[0-9]+\\(D\\) \[=!]= 0" "optimized" } } #include <new> #include <utility> diff --git a/gcc/testsuite/g++.dg/init/pr35878_4.C b/gcc/testsuite/g++.dg/init/pr35878_4.C new file mode 100644 index 0000000..bd27565 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr35878_4.C @@ -0,0 +1,23 @@ +// PR c++/35878 +// { dg-do compile } +// { dg-options "-O2 -std=gnu++11 -fcheck-new -fdump-tree-optimized" } +// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" } } + +#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); +}