[cfe-commits] r123966 - in /cfe/trunk: lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
Douglas Gregor
dgregor at apple.com
Thu Jan 20 21:18:22 PST 2011
Author: dgregor
Date: Thu Jan 20 23:18:22 2011
New Revision: 123966
URL: http://llvm.org/viewvc/llvm-project?rev=123966&view=rev
Log:
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.
Added:
cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp (with props)
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=123966&r1=123965&r2=123966&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Jan 20 23:18:22 2011
@@ -3013,8 +3013,7 @@
// 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 @@
!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 @@
(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 @@
ICS.UserDefined.After.ReferenceBinding = true;
ICS.UserDefined.After.RRefBinding = isRValRef;
}
+
return ICS;
}
@@ -4005,6 +4020,16 @@
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:
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=123966&r1=123965&r2=123966&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jan 20 23:18:22 2011
@@ -2399,6 +2399,18 @@
ParamType = ParamType.getLocalUnqualifiedType();
const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>();
if (ParamRefType) {
+ // [C++0x] If P is an rvalue reference to a cv-unqualified
+ // template parameter and the argument is an lvalue, the type
+ // "lvalue reference to A" is used in place of A for type
+ // deduction.
+ if (const RValueReferenceType *RValueRef
+ = dyn_cast<RValueReferenceType>(ParamType)) {
+ if (!RValueRef->getPointeeType().getQualifiers() &&
+ isa<TemplateTypeParmType>(RValueRef->getPointeeType()) &&
+ Arg->Classify(S.Context).isLValue())
+ ArgType = S.Context.getLValueReferenceType(ArgType);
+ }
+
// [...] If P is a reference type, the type referred to by P is used
// for type deduction.
ParamType = ParamRefType->getPointeeType();
Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp?rev=123966&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp Thu Jan 20 23:18:22 2011
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+
+// If P is an rvalue reference to a cv-unqualified template parameter
+// and the argument is an lvalue, the type "lvalue reference to A" is
+// used in place of A for type deduction.
+template<typename T> struct X { };
+
+template<typename T> X<T> f0(T&&);
+
+struct Y { };
+
+template<typename T> T prvalue();
+template<typename T> T&& xvalue();
+template<typename T> T& lvalue();
+
+void test_f0() {
+ X<int> xi0 = f0(prvalue<int>());
+ X<int> xi1 = f0(xvalue<int>());
+ X<int&> xi2 = f0(lvalue<int>());
+ X<Y> xy0 = f0(prvalue<Y>());
+ X<Y> xy1 = f0(xvalue<Y>());
+ X<Y&> xy2 = f0(lvalue<Y>());
+}
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list