aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-21 05:18:22 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-21 05:18:22 +0000
commit2ad746aeb90e86cea7afaf552a02ae3f3b5ec859 (patch)
treee5e80a65e5c0b46847fd11fa81c8028377f2fe6c /lib/Sema/SemaOverload.cpp
parentc80e8115278ba1537c8b517a083ecbd0a018b579 (diff)
Implement the special template argument deduction rule for T&& in a
call (C++0x [temp.deduct.call]p3). As part of this, start improving the reference-binding implementation used in the computation of implicit conversion sequences (for overload resolution) to reflect C++0x semantics. It still needs more work and testing, of course. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123966 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp31
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index c6150d91ec..e1318f9aab 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3013,8 +3013,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// qualifier.
// This is also the point where rvalue references and lvalue inits no longer
// go together.
- if ((!isRValRef && !T1.isConstQualified()) ||
- (isRValRef && InitCategory.isLValue()))
+ if (!isRValRef && !T1.isConstQualified())
return ICS;
// -- If T1 is a function type, then
@@ -3073,8 +3072,17 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
!S.RequireCompleteType(DeclLoc, T2, 0) &&
FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
Init, T2, /*AllowRvalues=*/true,
- AllowExplicit))
+ AllowExplicit)) {
+ // In the second case, if the reference is an rvalue reference
+ // and the second standard conversion sequence of the
+ // user-defined conversion sequence includes an lvalue-to-rvalue
+ // conversion, the program is ill-formed.
+ if (ICS.isUserDefined() && isRValRef &&
+ ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue)
+ ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType);
+
return ICS;
+ }
}
// -- Otherwise, a temporary of type "cv1 T1" is created and
@@ -3101,6 +3109,12 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
(T1->isRecordType() || T2->isRecordType()))
return ICS;
+ // If T1 is reference-related to T2 and the reference is an rvalue
+ // reference, the initializer expression shall not be an lvalue.
+ if (RefRelationship >= Sema::Ref_Related &&
+ isRValRef && Init->Classify(S.Context).isLValue())
+ 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
@@ -3123,6 +3137,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
ICS.UserDefined.After.ReferenceBinding = true;
ICS.UserDefined.After.RRefBinding = isRValRef;
}
+
return ICS;
}
@@ -4005,6 +4020,16 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Candidate.FailureKind = ovl_fail_final_conversion_not_exact;
}
+ // C++0x [dcl.init.ref]p5:
+ // In the second case, if the reference is an rvalue reference and
+ // the second standard conversion sequence of the user-defined
+ // conversion sequence includes an lvalue-to-rvalue conversion, the
+ // program is ill-formed.
+ if (ToType->isRValueReferenceType() &&
+ ICS.Standard.First == ICK_Lvalue_To_Rvalue) {
+ Candidate.Viable = false;
+ Candidate.FailureKind = ovl_fail_bad_final_conversion;
+ }
break;
case ImplicitConversionSequence::BadConversion: