decl.c (grok_op_properties): Don't complain about size_t placement delete here.
* decl.c (grok_op_properties): Don't complain about size_t placement delete here. * call.c (second_parm_is_size_t): Split out from... (non_placement_deallocation_fn_p): ...here. (build_op_delete_call): Warn about size_t placement delete with -Wc++14-compat. From-SVN: r223460
This commit is contained in:
parent
fa5cc2db54
commit
1210105350
@ -1,3 +1,12 @@
|
||||
2015-05-20 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* decl.c (grok_op_properties): Don't complain about size_t
|
||||
placement delete here.
|
||||
* call.c (second_parm_is_size_t): Split out from...
|
||||
(non_placement_deallocation_fn_p): ...here.
|
||||
(build_op_delete_call): Warn about size_t placement delete with
|
||||
-Wc++14-compat.
|
||||
|
||||
2015-05-19 Nathan sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/65954
|
||||
|
@ -5748,6 +5748,18 @@ build_new_op (location_t loc, enum tree_code code, int flags,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Returns true if FN has two parameters, of which the second has type
|
||||
size_t. */
|
||||
|
||||
static bool
|
||||
second_parm_is_size_t (tree fn)
|
||||
{
|
||||
tree t = FUNCTION_ARG_CHAIN (fn);
|
||||
return (t
|
||||
&& same_type_p (TREE_VALUE (t), size_type_node)
|
||||
&& TREE_CHAIN (t) == void_list_node);
|
||||
}
|
||||
|
||||
/* Returns true iff T, an element of an OVERLOAD chain, is a usual
|
||||
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */
|
||||
|
||||
@ -5768,11 +5780,9 @@ non_placement_deallocation_fn_p (tree t)
|
||||
of which has type std::size_t (18.2), then this function is a usual
|
||||
deallocation function. */
|
||||
bool global = DECL_NAMESPACE_SCOPE_P (t);
|
||||
t = FUNCTION_ARG_CHAIN (t);
|
||||
if (t == void_list_node
|
||||
|| (t && same_type_p (TREE_VALUE (t), size_type_node)
|
||||
&& (!global || flag_sized_deallocation)
|
||||
&& TREE_CHAIN (t) == void_list_node))
|
||||
if (FUNCTION_ARG_CHAIN (t) == void_list_node
|
||||
|| ((!global || flag_sized_deallocation)
|
||||
&& second_parm_is_size_t (t)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -5859,23 +5869,49 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||
function (3.7.4.2) and that function, considered as a placement
|
||||
deallocation function, would have been selected as a match for the
|
||||
allocation function, the program is ill-formed." */
|
||||
if (non_placement_deallocation_fn_p (fn))
|
||||
if (second_parm_is_size_t (fn))
|
||||
{
|
||||
const char *msg1
|
||||
= G_("exception cleanup for this placement new selects "
|
||||
"non-placement operator delete");
|
||||
const char *msg2
|
||||
= G_("%q+D is a usual (non-placement) deallocation "
|
||||
"function in C++14 (or with -fsized-deallocation)");
|
||||
|
||||
/* But if the class has an operator delete (void *), then that is
|
||||
the usual deallocation function, so we shouldn't complain
|
||||
about using the operator delete (void *, size_t). */
|
||||
for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
|
||||
t; t = OVL_NEXT (t))
|
||||
if (DECL_CLASS_SCOPE_P (fn))
|
||||
for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
|
||||
t; t = OVL_NEXT (t))
|
||||
{
|
||||
tree elt = OVL_CURRENT (t);
|
||||
if (non_placement_deallocation_fn_p (elt)
|
||||
&& FUNCTION_ARG_CHAIN (elt) == void_list_node)
|
||||
goto ok;
|
||||
}
|
||||
/* Before C++14 a two-parameter global deallocation function is
|
||||
always a placement deallocation function, but warn if
|
||||
-Wc++14-compat. */
|
||||
else if (!flag_sized_deallocation)
|
||||
{
|
||||
tree elt = OVL_CURRENT (t);
|
||||
if (non_placement_deallocation_fn_p (elt)
|
||||
&& FUNCTION_ARG_CHAIN (elt) == void_list_node)
|
||||
goto ok;
|
||||
if ((complain & tf_warning)
|
||||
&& warning (OPT_Wc__14_compat, msg1))
|
||||
inform (0, msg2, fn);
|
||||
goto ok;
|
||||
}
|
||||
if (complain & tf_error)
|
||||
|
||||
if (complain & tf_warning_or_error)
|
||||
{
|
||||
permerror (0, "non-placement deallocation function %q+D", fn);
|
||||
permerror (input_location, "selected for placement delete");
|
||||
if (permerror (input_location, msg1))
|
||||
{
|
||||
/* Only mention C++14 for namespace-scope delete. */
|
||||
if (DECL_NAMESPACE_SCOPE_P (fn))
|
||||
inform (0, msg2, fn);
|
||||
else
|
||||
inform (0, "%q+D is a usual (non-placement) deallocation "
|
||||
"function", fn);
|
||||
}
|
||||
}
|
||||
else
|
||||
return error_mark_node;
|
||||
|
@ -11767,16 +11767,6 @@ grok_op_properties (tree decl, bool complain)
|
||||
error ("%qD may not be declared as static", decl);
|
||||
return false;
|
||||
}
|
||||
if (!flag_sized_deallocation && warn_cxx14_compat)
|
||||
{
|
||||
tree parm = FUNCTION_ARG_CHAIN (decl);
|
||||
if (parm && same_type_p (TREE_VALUE (parm), size_type_node)
|
||||
&& TREE_CHAIN (parm) == void_list_node)
|
||||
warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc__14_compat,
|
||||
"%qD is a usual (non-placement) deallocation "
|
||||
"function in C++14 (or with -fsized-deallocation)",
|
||||
decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,26 @@
|
||||
// Test that -Wc++14-compat warns about the change in meaning.
|
||||
// { dg-options "-Wall" }
|
||||
// Test for a diagnostic about a usual deallocation function used as a
|
||||
// placement deallocation function. This will be a warning in C++98/11
|
||||
// modes and an error in C++14 mode.
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
void operator delete[] (void *p, size_t s) throw(); // { dg-warning "usual" "" { target { ! c++14 } } }
|
||||
// { dg-options "-Wc++14-compat" }
|
||||
|
||||
#include <new>
|
||||
void *operator new (std::size_t s, std::size_t)
|
||||
{
|
||||
return operator new (s);
|
||||
}
|
||||
|
||||
void operator delete (void *p, std::size_t) throw()
|
||||
{
|
||||
return ::operator delete (p);
|
||||
}
|
||||
|
||||
struct A
|
||||
{
|
||||
A();
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
new (42) A; // { dg-message "" }
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ struct A
|
||||
{
|
||||
A();
|
||||
void* operator new (size_t, size_t);
|
||||
void operator delete (void *, size_t); // { dg-error "non-placement" }
|
||||
void operator delete (void *, size_t); // { dg-message "non-placement" }
|
||||
};
|
||||
|
||||
struct B
|
||||
@ -27,6 +27,6 @@ struct B
|
||||
|
||||
int main()
|
||||
{
|
||||
A* ap = new (24) A; // { dg-error "placement delete" }
|
||||
A* ap = new (24) A; // { dg-error "placement" }
|
||||
B* bp = new (24) B;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user