Patchwork C++ PATCH for c++/60367 (wrong argument passing with {})

login
register
mail settings
Submitter Jason Merrill
Date March 10, 2014, 9:06 p.m.
Message ID <531E2946.80104@redhat.com>
Download mbox | patch
Permalink /patch/328832/
State New
Headers show

Comments

Jason Merrill - March 10, 2014, 9:06 p.m.
The problem was that we were failing to call convert_for_arg_passing 
when the default argument is a CONSTRUCTOR.  I wasn't sure why I had 
added the CONSTRUCTOR special case in the first place, and looked back 
in git blame to see when it had come in...and found that it dated back 
to a Cygnus G++ merge back in the mists of time.  So, not from the 
list-initialization work.

Removing the special case fixes the bug; I'm sure that whatever it was 
originally intended to handle is now handled by the list-init stuff.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 31ecb3e7f77979f602b20e1358201326c0e4eedd
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Mar 10 15:51:42 2014 -0400

    	PR c++/60367
    	* call.c (convert_default_arg): Remove special handling for
    	CONSTRUCTOR.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index b58c072..184e922 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6531,20 +6531,10 @@  convert_default_arg (tree type, tree arg, tree fn, int parmnum,
   /* We must make a copy of ARG, in case subsequent processing
      alters any part of it.  */
   arg = break_out_target_exprs (arg);
-  if (TREE_CODE (arg) == CONSTRUCTOR)
-    {
-      arg = digest_init (type, arg, complain);
-      arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
-					ICR_DEFAULT_ARGUMENT, fn, parmnum,
-                                        complain);
-    }
-  else
-    {
-      arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
-					ICR_DEFAULT_ARGUMENT, fn, parmnum,
-                                        complain);
-      arg = convert_for_arg_passing (type, arg, complain);
-    }
+  arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
+				    ICR_DEFAULT_ARGUMENT, fn, parmnum,
+				    complain);
+  arg = convert_for_arg_passing (type, arg, complain);
   pop_deferring_access_checks();
 
   pop_defarg_context ();
diff --git a/gcc/testsuite/g++.dg/overload/defarg8.C b/gcc/testsuite/g++.dg/overload/defarg8.C
new file mode 100644
index 0000000..b3ddfbb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/defarg8.C
@@ -0,0 +1,22 @@ 
+// PR c++/60367
+// { dg-do run { target c++11 } }
+
+extern "C" int printf (const char *, ...);
+extern "C" void abort();
+
+void *p;
+struct foo {
+  foo() { p = this; }
+  foo (const foo &) { abort(); }
+  ~foo() { if (p != this) abort(); }
+};
+
+void do_something( foo f = {} )
+{
+  if (&f != p) abort();
+}
+
+int main()
+{
+ do_something();
+}