[cfe-commits] r101712 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/SemaCXX/overload-call.cpp
Douglas Gregor
dgregor at apple.com
Sun Apr 18 02:22:01 PDT 2010
Author: dgregor
Date: Sun Apr 18 04:22:00 2010
New Revision: 101712
URL: http://llvm.org/viewvc/llvm-project?rev=101712&view=rev
Log:
When performing reference initialization for the purposes of overload
resolution ([over.ics.ref]), we take some shortcuts required by the
standard that effectively permit binding of a const volatile reference
to an rvalue. We have to treat lightly here to avoid infinite
recursion.
Fixes PR6177.
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/overload-call.cpp
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=101712&r1=101711&r2=101712&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Apr 18 04:22:00 2010
@@ -2308,20 +2308,23 @@
Sema::ReferenceCompareResult RefRelationship
= S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
- // C++ [dcl.init.ref]p5:
- // A reference to type "cv1 T1" is initialized by an expression
- // of type "cv2 T2" as follows:
-
- // -- If the initializer expression
// C++ [over.ics.ref]p3:
// Except for an implicit object parameter, for which see 13.3.1,
// a standard conversion sequence cannot be formed if it requires
// binding an lvalue reference to non-const to an rvalue or
// binding an rvalue reference to an lvalue.
+ //
+ // FIXME: DPG doesn't trust this code. It seems far too early to
+ // abort because of a binding of an rvalue reference to an lvalue.
if (isRValRef && InitLvalue == Expr::LV_Valid)
return ICS;
+ // C++0x [dcl.init.ref]p16:
+ // A reference to type "cv1 T1" is initialized by an expression
+ // of type "cv2 T2" as follows:
+
+ // -- If the initializer expression
// -- is an lvalue (but is not a bit-field), and "cv1 T1" is
// reference-compatible with "cv2 T2," or
//
@@ -2444,7 +2447,15 @@
// -- Otherwise, the reference shall be to a non-volatile const
// type (i.e., cv1 shall be const), or the reference shall be an
// rvalue reference and the initializer expression shall be an rvalue.
- if (!isRValRef && T1.getCVRQualifiers() != Qualifiers::Const)
+ //
+ // We actually handle one oddity of C++ [over.ics.ref] at this
+ // point, which is that, due to p2 (which short-circuits reference
+ // binding by only attempting a simple conversion for non-direct
+ // bindings) and p3's strange wording, we allow a const volatile
+ // reference to bind to an rvalue. Hence the check for the presence
+ // of "const" rather than checking for "const" being the only
+ // qualifier.
+ if (!isRValRef && !T1.isConstQualified())
return ICS;
// -- if T2 is a class type and
@@ -2508,7 +2519,6 @@
return ICS;
// C++ [over.ics.ref]p2:
- //
// When a parameter of reference type is not bound directly to
// an argument expression, the conversion sequence is the one
// required to convert the argument expression to the
Modified: cfe/trunk/test/SemaCXX/overload-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=101712&r1=101711&r2=101712&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overload-call.cpp (original)
+++ cfe/trunk/test/SemaCXX/overload-call.cpp Sun Apr 18 04:22:00 2010
@@ -247,14 +247,14 @@
int& cvqual_subsume(X&); // expected-note{{candidate function}}
float& cvqual_subsume(const Y&); // expected-note{{candidate function}}
-int& cvqual_subsume2(const X&);
-float& cvqual_subsume2(const volatile Y&);
+int& cvqual_subsume2(const X&); // expected-note{{candidate function}}
+float& cvqual_subsume2(const volatile Y&); // expected-note{{candidate function}}
Z get_Z();
void cvqual_subsume_test(Z z) {
cvqual_subsume(z); // expected-error{{call to 'cvqual_subsume' is ambiguous; candidates are:}}
- int& x = cvqual_subsume2(get_Z()); // okay: only binds to the first one
+ int& x = cvqual_subsume2(get_Z()); // expected-error{{call to 'cvqual_subsume2' is ambiguous; candidates are:}}
}
// Test overloading with cv-qualification differences in reference
@@ -421,3 +421,12 @@
S()(0); // expected-error{{conversion from 'int' to 'PR6078::A' is ambiguous}}
}
}
+
+namespace PR6177 {
+ struct String { String(char const*); };
+
+ void f(bool const volatile&);
+ void f(String);
+
+ void g() { f(""); } // expected-error{{volatile lvalue reference to type 'bool const volatile' cannot bind to a value of unrelated type 'char const [1]'}}
+}
More information about the cfe-commits
mailing list