This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] fix 32756


This patch fixes 32756 where we erroneously think there's an rvalue reference mismatch in overload resolution.

AFAICT, the existing code is not doing what the comment above says it should be doing:
/* [over.ics.rank]


     --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers
     to an implicit object parameter, and either S1 binds an lvalue reference
     to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue
     reference to an rvalue and S2 binds an lvalue reference
     (C++0x draft standard, 13.3.3.2)

     --S1 and S2 are reference bindings (_dcl.init.ref_), and the
     types to which the references refer are the same type except for
     top-level cv-qualifiers, and the type to which the reference
     initialized by S2 refers is more cv-qualified than the type to
     which the reference initialized by S1 refers */

This patch changes things so that we mark such bindings that are of an implicit object paramter (by setting this_p), and then skip such rvalue binding matching if one of the two conversions has this set.

Furthermore, it appears that the current code is only doing this check when the type is the same ignoring top level qualifiers, which is not what the above paragraphs indicate.

Doug, can you check my understanding, I'm a little rusty about these rvalue references...

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2007-08-27  Nathan Sidwell  <nathan@codesourcery.com>

	cp/
	PR c++/32756
	* call.c (maybe_handle_implicit_object): Set this_p, clear
	rvaluedness_matches_p.
	(compare_ics): Do not compare rvaluedness matching when one of the
	operands is an implicit object.

	testsuite/
	PR c++/32756
	* g++.dg/overload/operator3.C: New.

Index: testsuite/g++.dg/overload/operator3.C
===================================================================
--- testsuite/g++.dg/overload/operator3.C	(revision 0)
+++ testsuite/g++.dg/overload/operator3.C	(revision 0)
@@ -0,0 +1,31 @@
+// PR c++/32756
+// { dg-do compile }
+
+// bogus overload warning
+
+class QString;
+
+struct QByteArray
+{
+  QByteArray ();
+  bool operator!= (const QString & s2) const;
+};
+
+bool operator!= (const QByteArray & a1, const QByteArray & a2);
+
+struct QString
+{
+  QString ();
+  QString (const QByteArray & a);
+};
+
+QByteArray abbreviation ();
+
+void
+fromString ()
+{
+  QByteArray zoneAbbrev;
+  if (abbreviation () != zoneAbbrev)
+    {
+    }
+}
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 127828)
+++ cp/call.c	(working copy)
@@ -5762,7 +5838,8 @@ maybe_handle_implicit_object (conversion
 	t = t->u.next;
       t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE);
       t = direct_reference_binding (reference_type, t);
-      t->rvaluedness_matches_p = 1;
+      t->this_p = 1;
+      t->rvaluedness_matches_p = 0;
       *ics = t;
     }
 }
@@ -6121,18 +6198,21 @@ compare_ics (conversion *ics1, conversio
      initialized by S2 refers is more cv-qualified than the type to
      which the reference initialized by S1 refers */
 
-  if (ref_conv1 && ref_conv2
-      && same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+  if (ref_conv1 && ref_conv2)
     {
-      if (ref_conv1->rvaluedness_matches_p
-	  && !ref_conv2->rvaluedness_matches_p)
-	return 1;
-      else if (!ref_conv1->rvaluedness_matches_p
-	  && ref_conv2->rvaluedness_matches_p)
-	return -1;
+      if (!ref_conv1->this_p && !ref_conv2->this_p
+	  && (TYPE_REF_IS_RVALUE (ref_conv1->type)
+	      != TYPE_REF_IS_RVALUE (ref_conv2->type)))
+	{
+	  if (ref_conv1->rvaluedness_matches_p)
+	    return 1;
+	  if (ref_conv2->rvaluedness_matches_p)
+	    return -1;
+	}
 
-      return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
-				    TREE_TYPE (ref_conv1->type));
+      if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+	return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
+				      TREE_TYPE (ref_conv1->type));
     }
 
   /* Neither conversion sequence is better than the other.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]