diff options
author | ville <ville@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-03-21 06:36:22 +0000 |
---|---|---|
committer | ville <ville@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-03-21 06:36:22 +0000 |
commit | 4885982fc14ef6e0bac574be28e561cb0173ea50 (patch) | |
tree | d79677552e18d212e5b23a180aad1873e8e7c956 | |
parent | cc2ca70e38c84c79953f4c6571fe362d46b344fe (diff) |
gcc/
PR c++/35878
* cp/init.c (std_placement_new_fn_p): New.
(build_new_1): Call it.
testsuite/
PR c++/35878
* g++.dg/init/pr35878_1.C: New.
* g++.dg/init/pr35878_2.C: Likewise.
* g++.dg/init/pr35878_3.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@246301 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr35878_1.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr35878_2.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr35878_3.C | 21 |
5 files changed, 86 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7dfa57771ad..8264502e050 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-03-21 Ville Voutilainen <ville.voutilainen@gmail.com> + + PR c++/35878 + * cp/init.c (std_placement_new_fn_p): New. + (build_new_1): Call it. + 2017-03-20 Jason Merrill <jason@redhat.com> PR c++/80096 - ICE with C++17 non-type auto. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ebb1245d9c2..4ec26afa235 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2707,6 +2707,21 @@ malloc_alignment () return MAX (max_align_t_align(), MALLOC_ABI_ALIGNMENT); } +/* Determine whether an allocation function is a namespace-scope + non-replaceable placement new function. See DR 1748. + TODO: Enable in all standard modes. */ +static bool std_placement_new_fn_p (tree alloc_fn) +{ + if ((cxx_dialect > cxx14) && 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) + && TREE_CHAIN (first_arg) == void_list_node) + return true; + } + return false; +} + /* Generate code for a new-expression, including calling the "operator new" function, initializing the object, and, if an exception occurs during construction, cleaning up. The arguments are as for @@ -3185,7 +3200,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, So check for a null exception spec on the op new we just called. */ nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); - check_new = (flag_check_new || nothrow); + check_new = flag_check_new + || (nothrow && !std_placement_new_fn_p (alloc_fn)); if (cookie_size) { diff --git a/gcc/testsuite/g++.dg/init/pr35878_1.C b/gcc/testsuite/g++.dg/init/pr35878_1.C new file mode 100644 index 00000000000..b45c0097a93 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr35878_1.C @@ -0,0 +1,21 @@ +// { dg-options "-O2 --std=gnu++11" } +// { dg-do compile } +// { dg-final { scan-assembler "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); +} diff --git a/gcc/testsuite/g++.dg/init/pr35878_2.C b/gcc/testsuite/g++.dg/init/pr35878_2.C new file mode 100644 index 00000000000..066449419b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr35878_2.C @@ -0,0 +1,21 @@ +// { dg-options "-O2 --std=gnu++17 -fcheck-new" } +// { dg-do compile } +// { dg-final { scan-assembler "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); +} diff --git a/gcc/testsuite/g++.dg/init/pr35878_3.C b/gcc/testsuite/g++.dg/init/pr35878_3.C new file mode 100644 index 00000000000..8a5614f12ff --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr35878_3.C @@ -0,0 +1,21 @@ +// { dg-options "-O2 --std=gnu++17" } +// { 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); +} |