Commit ece3b7e6 by Ville Voutilainen Committed by Ville Voutilainen

re PR c++/35878 ([LWG 2302] Useless NULL pointer check when constructing object)

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.

From-SVN: r246301
parent 5b9e0383
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> 2017-03-20 Jason Merrill <jason@redhat.com>
PR c++/80096 - ICE with C++17 non-type auto. PR c++/80096 - ICE with C++17 non-type auto.
......
...@@ -2707,6 +2707,21 @@ malloc_alignment () ...@@ -2707,6 +2707,21 @@ malloc_alignment ()
return MAX (max_align_t_align(), MALLOC_ABI_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 /* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for 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, ...@@ -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. */ So check for a null exception spec on the op new we just called. */
nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); 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) if (cookie_size)
{ {
......
// { 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);
}
// { 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);
}
// { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment