This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] fix 32756
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: Doug Gregor <doug dot gregor at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 27 Aug 2007 13:30:35 +0100
- Subject: [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. */