diff mbox series

[C++,82560] missing dtor call

Message ID da3fa92c-a007-4f14-9572-fb14364c766c@acm.org
State New
Headers show
Series [C++,82560] missing dtor call | expand

Commit Message

Nathan Sidwell Oct. 17, 2017, 3:51 p.m. UTC
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
diff mbox series

Patch

2017-10-17  Nathan Sidwell  <nathan@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;;
+}