In a 'new T(whatever)' expression, we'll never call T::~T. We used to
generate such a cleanup (but then throw it away in optimization). But
now dtors can be deleted, so that approach could fail. My patch for
78469 fixed that. But caused this problem. The only cleanup we should
not be generating is for the object being newed. Like the decltype
handling in build_new_method_call, we shouldn't be passing no_cleanup
down either.
Applying to trunk.
nathan
--
Nathan Sidwell
2017-10-17 Nathan Sidwell <nat...@acm.org>
PR c++/82560
* call.c (build_over_call): Don't pass tf_no_cleanup to nested
calls.
PR c++/82560
* g++.dg/cpp0x/pr82560.C: New.
Index: cp/call.c
===================================================================
--- cp/call.c (revision 253819)
+++ cp/call.c (working copy)
@@ -7717,8 +7717,11 @@ build_over_call (struct z_candidate *can
}
/* N3276 magic doesn't apply to nested calls. */
- int decltype_flag = (complain & tf_decltype);
+ tsubst_flags_t decltype_flag = (complain & tf_decltype);
complain &= ~tf_decltype;
+ /* No-Cleanup doesn't apply to nested calls either. */
+ tsubst_flags_t no_cleanup_complain = complain;
+ complain &= ~tf_no_cleanup;
/* Find maximum size of vector to hold converted arguments. */
parmlen = list_length (parm);
@@ -7916,7 +7919,7 @@ build_over_call (struct z_candidate *can
if (flags & LOOKUP_NO_CONVERSION)
conv->user_conv_p = true;
- tsubst_flags_t arg_complain = complain & (~tf_no_cleanup);
+ tsubst_flags_t arg_complain = complain;
if (!conversion_warning)
arg_complain &= ~tf_warning;
@@ -8164,7 +8167,8 @@ build_over_call (struct z_candidate *can
else if (default_ctor_p (fn))
{
if (is_dummy_object (argarray[0]))
- return force_target_expr (DECL_CONTEXT (fn), void_node, complain);
+ return force_target_expr (DECL_CONTEXT (fn), void_node,
+ no_cleanup_complain);
else
return cp_build_indirect_ref (argarray[0], RO_NULL, complain);
}
@@ -9062,7 +9066,6 @@ build_new_method_call_1 (tree instance,
static member function. */
instance = mark_type_use (instance);
-
/* Figure out whether to skip the first argument for the error
message we will display to users if an error occurs. We don't
want to display any compiler-generated arguments. The "this"
Index: testsuite/g++.dg/cpp0x/pr82560.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr82560.C (revision 0)
+++ testsuite/g++.dg/cpp0x/pr82560.C (working copy)
@@ -0,0 +1,28 @@
+// { dg-do run { target c++11 } }
+// PR82560, failed to destruct default arg inside new
+
+static int liveness = 0;
+
+struct Foo {
+
+ Foo (int) {
+ liveness++;
+ }
+
+ ~Foo() {
+ liveness--;
+ }
+
+};
+
+struct Bar {
+ Bar (Foo = 0) { }
+ ~Bar() { }
+};
+
+int main()
+{
+ delete new Bar();
+
+ return liveness != 0;;
+}