Patchwork C++0x PATCH to improve diagnostics with deleted functions

login
register
mail settings
Submitter Jason Merrill
Date June 15, 2010, 7:31 p.m.
Message ID <4C17D515.8090806@redhat.com>
Download mbox | patch
Permalink /patch/55788/
State New
Headers show

Comments

Jason Merrill - June 15, 2010, 7:31 p.m.
As an extension, g++ will sometimes resolve a call to an overloaded 
function that the standard says is ambiguous (with an unconditional 
pedwarn).  It doesn't make much sense to choose a deleted function this 
way (giving that pedwarn) and then turn around and give an error about 
calling a deleted function.

Also, when printing a list of candidates for a failed overload 
resolution, we were dropping deleted functions which were viable 
candidates.  We should only elide ones that are not viable.

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

Patch

commit 395c33cab4ccb366f7cc51c4bc275fbc8ecc80fb
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jun 15 12:18:58 2010 -0400

    	* call.c (print_z_candidates): Do print viable deleted candidates.
    	(joust): Don't choose a deleted function just because its worst
    	conversion is better than another candidate's worst.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 60d7333..a735dc6 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2747,11 +2747,12 @@  print_z_candidates (struct z_candidate *candidates)
   if (!candidates)
     return;
 
-  /* Remove deleted candidates.  */
+  /* Remove non-viable deleted candidates.  */
   cand1 = candidates;
   for (cand2 = &cand1; *cand2; )
     {
       if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+	  && !(*cand2)->viable
 	  && DECL_DELETED_FN ((*cand2)->fn))
 	*cand2 = (*cand2)->next;
       else
@@ -7407,6 +7408,9 @@  tweak:
 	winner = -1, w = cand2, l = cand1;
       if (winner)
 	{
+	  /* Don't choose a deleted function over ambiguity.  */
+	  if (DECL_P (w->fn) && DECL_DELETED_FN (w->fn))
+	    return 0;
 	  if (warn)
 	    {
 	      pedwarn (input_location, 0,
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted18.C b/gcc/testsuite/g++.dg/cpp0x/defaulted18.C
new file mode 100644
index 0000000..ae055e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted18.C
@@ -0,0 +1,9 @@ 
+// { dg-options "-std=c++0x" }
+
+void f(char i, int j) = delete;	// { dg-message "<deleted>" }
+void f(int i, ...);		// { dg-message "void f" }
+
+int main()
+{
+  f(1,1);			// { dg-error "ambiguous" }
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/cons/assign_neg.cc b/libstdc++-v3/testsuite/29_atomics/atomic/cons/assign_neg.cc
index b7cb05d..c56678c 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/cons/assign_neg.cc
@@ -28,20 +28,5 @@  int main()
   return 0;
 }
 
-// { dg-error "used here" "" { target *-*-* } 522 }
-// { dg-error "deleted function" "" { target *-*-* } 230 }
-// { dg-error "deleted function" "" { target *-*-* } 248 }
-// { dg-error "deleted function" "" { target *-*-* } 266 }
-// { dg-error "deleted function" "" { target *-*-* } 284 }
-// { dg-error "deleted function" "" { target *-*-* } 302 }
-// { dg-error "deleted function" "" { target *-*-* } 320 }
-// { dg-error "deleted function" "" { target *-*-* } 338 }
-// { dg-error "deleted function" "" { target *-*-* } 356 }
-// { dg-error "deleted function" "" { target *-*-* } 374 }
-// { dg-error "deleted function" "" { target *-*-* } 392 }
-// { dg-error "deleted function" "" { target *-*-* } 410 }
-// { dg-error "deleted function" "" { target *-*-* } 428 }
-// { dg-error "deleted function" "" { target *-*-* } 446 }
-// { dg-error "deleted function" "" { target *-*-* } 464 }
-// { dg-error "deleted function" "" { target *-*-* } 482 }
+// { dg-error "ambiguous" "" { target *-*-* } 522 }
 // { dg-excess-errors "In member function" }
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/assign_neg.cc b/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/assign_neg.cc
index 0ec1321..ac4c567 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/assign_neg.cc
@@ -26,7 +26,6 @@  void test01()
   typedef std::atomic_address test_type;
   test_type t1;
   test_type t2;
-  t1 = t2;
+  t1 = t2;			// { dg-error "ambiguous" }
 }
-// { dg-error "used here" "" { target *-*-* } 29 }
 // { dg-excess-errors "deleted function" }
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/cons/assign_neg.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/cons/assign_neg.cc
index b5fc5c3..875906f 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_integral/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/cons/assign_neg.cc
@@ -29,12 +29,5 @@  int main()
   return 0;
 }
 
-// { dg-error "used here" "" { target *-*-* } 522 }
-// { dg-excess-errors "deleted function" }
-// { dg-excess-errors "deleted function" }
-// { dg-error "instantiated from" "" { target *-*-* } 28 }
-// { dg-error "instantiated from" "" { target *-*-* } 529 }
-// { dg-error "instantiated from" "" { target *-*-* } 170 }
-// { dg-error "instantiated from" "" { target *-*-* } 399 }
-// { dg-error "instantiated from" "" { target *-*-* } 168 }
+// { dg-error "ambiguous" "" { target *-*-* } 522 }
 // { dg-excess-errors "In member function" }