Patchwork C++ PATCH for c++/46831 (ICE with non-viable template conversion candidate)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 21, 2011, 1:47 a.m.
Message ID <4D61C42C.2010901@redhat.com>
Download mbox | patch
Permalink /patch/83772/
State New
Headers show

Comments

Jason Merrill - Feb. 21, 2011, 1:47 a.m.
convert_class_to_reference tries to massage candidates to provide the 
correct second standard conversion sequence, but that doesn't make any 
sense for candidates that are already known to be non-viable.  And crashes.

Tested x86_64-pc-linux-gnu, applied to trunk.
commit 89b2cae8887f41a5c181b3c55fd24710cb78048c
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Feb 20 18:30:10 2011 -0500

    	PR c++/46831
    	* call.c (convert_class_to_reference): Don't try to set up a
    	second conv sequence for non-viable candidates.

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7d602b9..078542a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1230,8 +1230,10 @@  convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
 	     rvalue of the right type is good enough.  */
 	  tree f = cand->fn;
 	  tree t2 = TREE_TYPE (TREE_TYPE (f));
-	  if (TREE_CODE (t2) != REFERENCE_TYPE
-	      || !reference_compatible_p (t, TREE_TYPE (t2)))
+	  if (cand->viable == 0)
+	    /* Don't bother looking more closely.  */;
+	  else if (TREE_CODE (t2) != REFERENCE_TYPE
+		   || !reference_compatible_p (t, TREE_TYPE (t2)))
 	    {
 	      /* No need to set cand->reason here; this is most likely
 		 an ambiguous match.  If it's not, either this candidate
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C
new file mode 100644
index 0000000..12cc836
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C
@@ -0,0 +1,14 @@ 
+// PR c++/46831
+// { dg-options -std=c++0x }
+
+struct B { };
+struct D : B { };
+struct A {
+  template<typename T = void> operator D&();
+  operator long();
+};
+
+void f(long);
+void f(B&);
+
+int main() { f(A()); }