summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-18 09:22:00 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-18 09:22:00 +0000
commit870f3743e48838827244763ef1c3e9ecdd1fbb0c (patch)
treed75df0ea015d6046cf0c8f2216fe9376f156429d /clang/lib
parent5b4be748cb992dc65296548f540b953d95420355 (diff)
downloadbcm5719-llvm-870f3743e48838827244763ef1c3e9ecdd1fbb0c.tar.gz
bcm5719-llvm-870f3743e48838827244763ef1c3e9ecdd1fbb0c.zip
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. llvm-svn: 101712
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f9cf1e90420..6772672bef1 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2308,20 +2308,23 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
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 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// -- 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 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
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
OpenPOWER on IntegriCloud