aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-05-20 17:32:46 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-05-20 17:32:46 -0400
commit1210105350eff9956347a4c0a3ae09d0514b81d0 (patch)
treeb96971c70160c7e2f7a222ef037214dd9673be82 /gcc/cp
parentfa5cc2db547120c41a1f1708039ad54b9dd171ea (diff)
downloadgcc-1210105350eff9956347a4c0a3ae09d0514b81d0.zip
gcc-1210105350eff9956347a4c0a3ae09d0514b81d0.tar.gz
gcc-1210105350eff9956347a4c0a3ae09d0514b81d0.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c66
-rw-r--r--gcc/cp/decl.c10
3 files changed, 60 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cb9219d..320023a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 07ccea9..bad49f1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 261a12d..e4d3c1d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
- }
}
}