[cfe-commits] r124033 - in /cfe/trunk: lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp test/SemaCXX/conditional-expr.cpp
Rafael Espindola
rafael.espindola at gmail.com
Sat Jan 22 07:32:35 PST 2011
Author: rafael
Date: Sat Jan 22 09:32:35 2011
New Revision: 124033
URL: http://llvm.org/viewvc/llvm-project?rev=124033&view=rev
Log:
revert r123977 and r123978 to fix PR9026.
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
cfe/trunk/test/SemaCXX/conditional-expr.cpp
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=124033&r1=124032&r2=124033&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jan 22 09:32:35 2011
@@ -2798,6 +2798,10 @@
CXXRecordDecl *T2RecordDecl
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
+ QualType ToType
+ = AllowRvalues? DeclType->getAs<ReferenceType>()->getPointeeType()
+ : DeclType;
+
OverloadCandidateSet CandidateSet(DeclLoc);
const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
@@ -2848,10 +2852,10 @@
if (ConvTemplate)
S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
- Init, DeclType, CandidateSet);
+ Init, ToType, CandidateSet);
else
S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
- DeclType, CandidateSet);
+ ToType, CandidateSet);
}
OverloadCandidateSet::iterator Best;
@@ -2940,7 +2944,9 @@
// of type "cv2 T2" as follows:
// -- If reference is an lvalue reference and the initializer expression
- if (!isRValRef) {
+ // The next bullet point (T1 is a function) is pretty much equivalent to this
+ // one, so it's handled here.
+ if (!isRValRef || T1->isFunctionType()) {
// -- is an lvalue (but is not a bit-field), and "cv1 T1" is
// reference-compatible with "cv2 T2," or
//
@@ -2995,7 +3001,8 @@
// -- Otherwise, the reference shall be an lvalue reference to a
// non-volatile const type (i.e., cv1 shall be const), or the reference
- // shall be an rvalue reference.
+ // shall be an rvalue reference and the initializer expression shall be
+ // an rvalue or have a function type.
//
// We actually handle one oddity of C++ [over.ics.ref] at this
// point, which is that, due to p2 (which short-circuits reference
@@ -3009,63 +3016,74 @@
if (!isRValRef && !T1.isConstQualified())
return ICS;
- // -- If the initializer expression
- //
- // -- is an xvalue, class prvalue, array prvalue or function
- // lvalue and "cv1T1" is reference-compatible with "cv2 T2", or
- if (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification &&
- (InitCategory.isXValue() ||
- (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) ||
- (InitCategory.isLValue() && T2->isFunctionType()))) {
- ICS.setStandard();
- ICS.Standard.First = ICK_Identity;
- ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
- : ObjCConversion? ICK_Compatible_Conversion
- : ICK_Identity;
- ICS.Standard.Third = ICK_Identity;
- ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
- ICS.Standard.setToType(0, T2);
- ICS.Standard.setToType(1, T1);
- ICS.Standard.setToType(2, T1);
- ICS.Standard.ReferenceBinding = true;
- // In C++0x, this is always a direct binding. In C++98/03, it's a direct
- // binding unless we're binding to a class prvalue.
- // Note: Although xvalues wouldn't normally show up in C++98/03 code, we
- // allow the use of rvalue references in C++98/03 for the benefit of
- // standard library implementors; therefore, we need the xvalue check here.
- ICS.Standard.DirectBinding =
- S.getLangOptions().CPlusPlus0x ||
- (InitCategory.isPRValue() && !T2->isRecordType());
- ICS.Standard.RRefBinding = isRValRef;
- ICS.Standard.CopyConstructor = 0;
- return ICS;
- }
-
- // -- has a class type (i.e., T2 is a class type), where T1 is not
- // reference-related to T2, and can be implicitly converted to
- // an xvalue, class prvalue, or function lvalue of type
- // "cv3 T3", where "cv1 T1" is reference-compatible with
- // "cv3 T3",
- //
- // then the reference is bound to the value of the initializer
- // expression in the first case and to the result of the conversion
- // in the second case (or, in either case, to an appropriate base
- // class subobject).
- if (T2->isRecordType() && RefRelationship == Sema::Ref_Incompatible &&
- !S.RequireCompleteType(DeclLoc, T2, 0) &&
- FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
- Init, T2, /*AllowRvalues=*/true,
- 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);
-
+ // -- If T1 is a function type, then
+ // -- if T2 is the same type as T1, the reference is bound to the
+ // initializer expression lvalue;
+ // -- if T2 is a class type and the initializer expression can be
+ // implicitly converted to an lvalue of type T1 [...], the
+ // reference is bound to the function lvalue that is the result
+ // of the conversion;
+ // This is the same as for the lvalue case above, so it was handled there.
+ // -- otherwise, the program is ill-formed.
+ // This is the one difference to the lvalue case.
+ if (T1->isFunctionType())
return ICS;
- }
+
+ // -- Otherwise, if T2 is a class type and
+ // -- the initializer expression is an rvalue and "cv1 T1"
+ // is reference-compatible with "cv2 T2," or
+ //
+ // -- T1 is not reference-related to T2 and the initializer
+ // expression can be implicitly converted to an rvalue
+ // of type "cv3 T3" (this conversion is selected by
+ // enumerating the applicable conversion functions
+ // (13.3.1.6) and choosing the best one through overload
+ // resolution (13.3)),
+ //
+ // then the reference is bound to the initializer
+ // expression rvalue in the first case and to the object
+ // that is the result of the conversion in the second case
+ // (or, in either case, to the appropriate base class
+ // subobject of the object).
+ if (T2->isRecordType()) {
+ // First case: "cv1 T1" is reference-compatible with "cv2 T2". This is a
+ // direct binding in C++0x but not in C++03.
+ if (InitCategory.isRValue() &&
+ RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+ ICS.setStandard();
+ ICS.Standard.First = ICK_Identity;
+ ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+ : ObjCConversion? ICK_Compatible_Conversion
+ : ICK_Identity;
+ ICS.Standard.Third = ICK_Identity;
+ ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+ ICS.Standard.setToType(0, T2);
+ ICS.Standard.setToType(1, T1);
+ ICS.Standard.setToType(2, T1);
+ ICS.Standard.ReferenceBinding = true;
+ ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
+ ICS.Standard.RRefBinding = isRValRef;
+ ICS.Standard.CopyConstructor = 0;
+ return ICS;
+ }
+
+ // Second case: not reference-related.
+ if (RefRelationship == Sema::Ref_Incompatible &&
+ !S.RequireCompleteType(DeclLoc, T2, 0) &&
+ FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+ Init, T2, /*AllowRvalues=*/true,
+ 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
// initialized from the initializer expression using the
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124033&r1=124032&r2=124033&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Jan 22 09:32:35 2011
@@ -2470,7 +2470,6 @@
TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
unsigned ArgIdx = 0;
- LocalInstantiationScope InstScope(*this, true);
while (Param != ParamEnd) {
if (ArgIdx > NumArgs && PartialTemplateArgs)
break;
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp?rev=124033&r1=124032&r2=124033&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp Sat Jan 22 09:32:35 2011
@@ -17,7 +17,7 @@
template<typename T>
struct ConvertsTo {
- operator T(); // expected-note 4{{candidate function}}
+ operator T(); // expected-note 2{{candidate function}}
};
void test_rvalue_refs() {
@@ -130,35 +130,3 @@
double&& rrd3 = i;
}
-namespace argument_passing {
- void base_rvalue_ref(Base&&);
- void int_rvalue_ref(int&&); // expected-note 2{{passing argument to parameter here}}
- void array_rvalue_ref(int (&&)[5]);
- void function_rvalue_ref(int (&&)(int));
-
- void test() {
- base_rvalue_ref(xvalue<Base>());
- base_rvalue_ref(xvalue<Derived>());
- int_rvalue_ref(xvalue<int>());
-
- base_rvalue_ref(prvalue<Base>());
- base_rvalue_ref(prvalue<Derived>());
-
- array_rvalue_ref(HasArray().array);
-
- function_rvalue_ref(f);
-
- base_rvalue_ref(ConvertsTo<Base&&>());
- base_rvalue_ref(ConvertsTo<Derived&&>());
- int_rvalue_ref(ConvertsTo<int&&>());
-
- base_rvalue_ref(ConvertsTo<Base>());
- base_rvalue_ref(ConvertsTo<Derived>());
-
- function_rvalue_ref(ConvertsTo<int(&)(int)>());
-
- int_rvalue_ref(ConvertsTo<int&>()); // expected-error{{no viable conversion from 'ConvertsTo<int &>' to 'int'}}
- int_rvalue_ref(ConvertsTo<float&>()); // expected-error{{no viable conversion from 'ConvertsTo<float &>' to 'int'}}
- }
-
-}
Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=124033&r1=124032&r2=124033&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Sat Jan 22 09:32:35 2011
@@ -7,10 +7,7 @@
struct ToBool { explicit operator bool(); };
struct B;
-struct A { // expected-note 2{{candidate is the implicit copy constructor}}
- A();
- A(const B&); // expected-note 2 {{candidate constructor}}
-};
+struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}}
struct B { operator A() const; }; // expected-note 2 {{candidate function}}
struct I { operator int(); };
struct J { operator I(); };
More information about the cfe-commits
mailing list