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;;
+}

Reply via email to