Patchwork C++ PATCH for c++/50523 (bogus ambiguity error regression on tramp3d)

login
register
mail settings
Submitter Jason Merrill
Date Sept. 26, 2011, 3:50 p.m.
Message ID <4E809F37.5040405@redhat.com>
Download mbox | patch
Permalink /patch/116440/
State New
Headers show

Comments

Jason Merrill - Sept. 26, 2011, 3:50 p.m.
build_user_type_conversion_1 complains about ambiguity if 
LOOKUP_COMPLAIN is set, so we need to avoid setting that flag when we 
call the function from reference_binding.  It seems to make sense to 
mask away all inappropriate lookup flags at the top of 
implicit_conversion rather than doing it further down and also in 
reference_binding.

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

Patch

commit 85372e79ba7d8786db4fc3c85c5272a8e037df99
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Sep 26 10:25:55 2011 -0400

    	PR c++/50523
    	* call.c (implicit_conversion): Mask out inappropriate LOOKUP
    	flags at the top of the function.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6a7dfd3..579e563 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1660,6 +1660,12 @@  implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
       || expr == error_mark_node)
     return NULL;
 
+  /* Other flags only apply to the primary function in overload
+     resolution, or after we've chosen one.  */
+  flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
+	    |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
+	    |LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
+
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, c_cast_p, flags);
   else
@@ -1716,15 +1722,13 @@  implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
       && (flags & LOOKUP_NO_CONVERSION) == 0)
     {
       struct z_candidate *cand;
-      int convflags = (flags & (LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING
-				|LOOKUP_NO_NARROWING));
 
       if (CLASS_TYPE_P (to)
 	  && BRACE_ENCLOSED_INITIALIZER_P (expr)
 	  && !CLASSTYPE_NON_AGGREGATE (complete_type (to)))
 	return build_aggr_conv (to, expr, flags);
 
-      cand = build_user_type_conversion_1 (to, expr, convflags);
+      cand = build_user_type_conversion_1 (to, expr, flags);
       if (cand)
 	conv = cand->second_conv;
 
diff --git a/gcc/testsuite/g++.dg/overload/ref-conv2.C b/gcc/testsuite/g++.dg/overload/ref-conv2.C
new file mode 100644
index 0000000..bb0ad39
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/ref-conv2.C
@@ -0,0 +1,15 @@ 
+// PR c++/50523
+
+template <class T>
+struct A
+{
+  A(const T&);
+  operator T&() const;
+  operator const T&() const;
+};
+
+int main()
+{
+  A<int> a(1);
+  A<int> a2(a);
+}