aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorville <ville@138bc75d-0d04-0410-961f-82ee72b054a4>2017-03-21 06:36:22 +0000
committerville <ville@138bc75d-0d04-0410-961f-82ee72b054a4>2017-03-21 06:36:22 +0000
commit4885982fc14ef6e0bac574be28e561cb0173ea50 (patch)
treed79677552e18d212e5b23a180aad1873e8e7c956
parentcc2ca70e38c84c79953f4c6571fe362d46b344fe (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/ChangeLog6
-rw-r--r--gcc/cp/init.c18
-rw-r--r--gcc/testsuite/g++.dg/init/pr35878_1.C21
-rw-r--r--gcc/testsuite/g++.dg/init/pr35878_2.C21
-rw-r--r--gcc/testsuite/g++.dg/init/pr35878_3.C21
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);
+}