We need to mask off tf_cleanup when we're dealing with argument
conversions; it should only apply to the top level call.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 833d39a7919caa021848861e2035c8a1ac3e3b51
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Feb 22 16:55:24 2017 -0800

            PR c++/79679 - missing destructor for argument
            * call.c (build_over_call): Don't pass tf_no_cleanup to argument
            conversions.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 93fae0d..f7924f0 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7838,12 +7838,13 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
       if (flags & LOOKUP_NO_CONVERSION)
        conv->user_conv_p = true;
 
+      tsubst_flags_t arg_complain = complain & (~tf_no_cleanup);
+      if (!conversion_warning)
+       arg_complain &= ~tf_warning;
+
       val = convert_like_with_context (conv, arg, fn, i - is_method,
-                                      conversion_warning
-                                      ? complain
-                                      : complain & (~tf_warning));
-
-      val = convert_for_arg_passing (type, val, complain);
+                                      arg_complain);
+      val = convert_for_arg_passing (type, val, arg_complain);
        
       if (val == error_mark_node)
         return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/init/cleanup4.C 
b/gcc/testsuite/g++.dg/init/cleanup4.C
new file mode 100644
index 0000000..b9769e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/cleanup4.C
@@ -0,0 +1,22 @@
+// PR c++/79679
+// { dg-do run }
+
+int count;
+struct S {
+    S() { ++count; }
+    S(const S&) { ++count; }
+    ~S() { --count; }
+};
+
+struct T {
+    T(S) {}
+};
+
+int main() {
+  {
+    S s;
+    T u(s);
+  }
+  if (count)
+    __builtin_abort();
+}

Reply via email to