forked from OSchip/llvm-project
Revert Sebastian's rvalue patch (r67870) since it caused test failures in
SemaCXX//overload-member-call.cpp SemaCXX//overloaded-operator.cpp SemaTemplate//instantiate-method.cpp llvm-svn: 67912
This commit is contained in:
parent
66918ee148
commit
72f307a26e
|
@ -55,7 +55,7 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
|
||||||
|
|
||||||
const CXXBaseSpecifier *InacessibleBase = 0;
|
const CXXBaseSpecifier *InacessibleBase = 0;
|
||||||
|
|
||||||
CXXRecordDecl* CurrentClassDecl = 0;
|
const CXXRecordDecl* CurrentClassDecl = 0;
|
||||||
if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(getCurFunctionDecl()))
|
if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(getCurFunctionDecl()))
|
||||||
CurrentClassDecl = MD->getParent();
|
CurrentClassDecl = MD->getParent();
|
||||||
|
|
||||||
|
@ -79,21 +79,9 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
|
||||||
if (CurrentClassDecl != Element->Class)
|
if (CurrentClassDecl != Element->Class)
|
||||||
FoundInaccessibleBase = true;
|
FoundInaccessibleBase = true;
|
||||||
break;
|
break;
|
||||||
case AS_protected:
|
case AS_protected:
|
||||||
// FIXME: Check if the current function/class is a friend.
|
// FIXME: Implement
|
||||||
if (!CurrentClassDecl) {
|
break;
|
||||||
FoundInaccessibleBase = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentClassDecl != Element->Class) {
|
|
||||||
QualType CurrentClassType = Context.getTypeDeclType(CurrentClassDecl);
|
|
||||||
QualType ClassType = Context.getTypeDeclType(Element->Class);
|
|
||||||
|
|
||||||
if (!IsDerivedFrom(CurrentClassType, ClassType))
|
|
||||||
FoundInaccessibleBase = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FoundInaccessibleBase) {
|
if (FoundInaccessibleBase) {
|
||||||
|
|
|
@ -1970,18 +1970,6 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
|
|
||||||
// -- If the initializer expression
|
// -- If the initializer expression
|
||||||
|
|
||||||
// Rvalue references cannot bind to lvalues (N2812).
|
|
||||||
// There is absolutely no situation where they can. In particular, note that
|
|
||||||
// this is ill-formed, even if B has a user-defined conversion to A&&:
|
|
||||||
// B b;
|
|
||||||
// A&& r = b;
|
|
||||||
if (isRValRef && InitLvalue == Expr::LV_Valid) {
|
|
||||||
if (!ICS)
|
|
||||||
Diag(Init->getSourceRange().getBegin(), diag::err_lvalue_to_rvalue_ref)
|
|
||||||
<< Init->getSourceRange();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BindsDirectly = false;
|
bool BindsDirectly = false;
|
||||||
// -- is an lvalue (but is not a bit-field), and “cv1 T1” is
|
// -- is an lvalue (but is not a bit-field), and “cv1 T1” is
|
||||||
// reference-compatible with “cv2 T2,” or
|
// reference-compatible with “cv2 T2,” or
|
||||||
|
@ -1992,6 +1980,14 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
RefRelationship >= Ref_Compatible_With_Added_Qualification) {
|
RefRelationship >= Ref_Compatible_With_Added_Qualification) {
|
||||||
BindsDirectly = true;
|
BindsDirectly = true;
|
||||||
|
|
||||||
|
// Rvalue references cannot bind to lvalues (N2812).
|
||||||
|
if (isRValRef) {
|
||||||
|
if (!ICS)
|
||||||
|
Diag(Init->getSourceRange().getBegin(), diag::err_lvalue_to_rvalue_ref)
|
||||||
|
<< Init->getSourceRange();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (ICS) {
|
if (ICS) {
|
||||||
// C++ [over.ics.ref]p1:
|
// C++ [over.ics.ref]p1:
|
||||||
// When a parameter of reference type binds directly (8.5.3)
|
// When a parameter of reference type binds directly (8.5.3)
|
||||||
|
@ -2008,7 +2004,6 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
ICS->Standard.ToTypePtr = T1.getAsOpaquePtr();
|
ICS->Standard.ToTypePtr = T1.getAsOpaquePtr();
|
||||||
ICS->Standard.ReferenceBinding = true;
|
ICS->Standard.ReferenceBinding = true;
|
||||||
ICS->Standard.DirectBinding = true;
|
ICS->Standard.DirectBinding = true;
|
||||||
ICS->Standard.RRefBinding = false;
|
|
||||||
|
|
||||||
// Nothing more to do: the inaccessibility/ambiguity check for
|
// Nothing more to do: the inaccessibility/ambiguity check for
|
||||||
// derived-to-base conversions is suppressed when we're
|
// derived-to-base conversions is suppressed when we're
|
||||||
|
@ -2116,8 +2111,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Otherwise, the reference shall be to a non-volatile const
|
// -- Otherwise, the reference shall be to a non-volatile const
|
||||||
// type (i.e., cv1 shall be const), or the reference shall be an
|
// type (i.e., cv1 shall be const), or shall be an rvalue reference.
|
||||||
// rvalue reference and the initializer expression shall be an rvalue.
|
|
||||||
if (!isRValRef && T1.getCVRQualifiers() != QualType::Const) {
|
if (!isRValRef && T1.getCVRQualifiers() != QualType::Const) {
|
||||||
if (!ICS)
|
if (!ICS)
|
||||||
Diag(Init->getSourceRange().getBegin(),
|
Diag(Init->getSourceRange().getBegin(),
|
||||||
|
@ -2146,7 +2140,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
// shall be callable whether or not the copy is actually
|
// shall be callable whether or not the copy is actually
|
||||||
// done.
|
// done.
|
||||||
//
|
//
|
||||||
// Note that C++0x [dcl.init.ref]p5 takes away this implementation
|
// Note that C++0x [dcl.ref.init]p5 takes away this implementation
|
||||||
// freedom, so we will always take the first option and never build
|
// freedom, so we will always take the first option and never build
|
||||||
// a temporary in this case. FIXME: We will, however, have to check
|
// a temporary in this case. FIXME: We will, however, have to check
|
||||||
// for the presence of a copy constructor in C++98/03 mode.
|
// for the presence of a copy constructor in C++98/03 mode.
|
||||||
|
@ -2160,8 +2154,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
ICS->Standard.FromTypePtr = T2.getAsOpaquePtr();
|
ICS->Standard.FromTypePtr = T2.getAsOpaquePtr();
|
||||||
ICS->Standard.ToTypePtr = T1.getAsOpaquePtr();
|
ICS->Standard.ToTypePtr = T1.getAsOpaquePtr();
|
||||||
ICS->Standard.ReferenceBinding = true;
|
ICS->Standard.ReferenceBinding = true;
|
||||||
ICS->Standard.DirectBinding = false;
|
ICS->Standard.DirectBinding = false;
|
||||||
ICS->Standard.RRefBinding = isRValRef;
|
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Binding to a subobject of the rvalue is going to require
|
// FIXME: Binding to a subobject of the rvalue is going to require
|
||||||
// more AST annotation than this.
|
// more AST annotation than this.
|
||||||
|
@ -2206,27 +2199,18 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType,
|
||||||
|
|
||||||
// Actually try to convert the initializer to T1.
|
// Actually try to convert the initializer to T1.
|
||||||
if (ICS) {
|
if (ICS) {
|
||||||
// C++ [over.ics.ref]p2:
|
/// C++ [over.ics.ref]p2:
|
||||||
//
|
///
|
||||||
// When a parameter of reference type is not bound directly to
|
/// When a parameter of reference type is not bound directly to
|
||||||
// an argument expression, the conversion sequence is the one
|
/// an argument expression, the conversion sequence is the one
|
||||||
// required to convert the argument expression to the
|
/// required to convert the argument expression to the
|
||||||
// underlying type of the reference according to
|
/// underlying type of the reference according to
|
||||||
// 13.3.3.1. Conceptually, this conversion sequence corresponds
|
/// 13.3.3.1. Conceptually, this conversion sequence corresponds
|
||||||
// to copy-initializing a temporary of the underlying type with
|
/// to copy-initializing a temporary of the underlying type with
|
||||||
// the argument expression. Any difference in top-level
|
/// the argument expression. Any difference in top-level
|
||||||
// cv-qualification is subsumed by the initialization itself
|
/// cv-qualification is subsumed by the initialization itself
|
||||||
// and does not constitute a conversion.
|
/// and does not constitute a conversion.
|
||||||
*ICS = TryImplicitConversion(Init, T1, SuppressUserConversions);
|
*ICS = TryImplicitConversion(Init, T1, SuppressUserConversions);
|
||||||
// Of course, that's still a reference binding.
|
|
||||||
if (ICS->ConversionKind == ImplicitConversionSequence::StandardConversion) {
|
|
||||||
ICS->Standard.ReferenceBinding = true;
|
|
||||||
ICS->Standard.RRefBinding = isRValRef;
|
|
||||||
} else if(ICS->ConversionKind ==
|
|
||||||
ImplicitConversionSequence::UserDefinedConversion) {
|
|
||||||
ICS->UserDefined.After.ReferenceBinding = true;
|
|
||||||
ICS->UserDefined.After.RRefBinding = isRValRef;
|
|
||||||
}
|
|
||||||
return ICS->ConversionKind == ImplicitConversionSequence::BadConversion;
|
return ICS->ConversionKind == ImplicitConversionSequence::BadConversion;
|
||||||
} else {
|
} else {
|
||||||
return PerformImplicitConversion(Init, T1, "initializing");
|
return PerformImplicitConversion(Init, T1, "initializing");
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace clang {
|
||||||
const CXXBaseSpecifier *Base;
|
const CXXBaseSpecifier *Base;
|
||||||
|
|
||||||
/// Class - The record decl of the class that the base is a base of.
|
/// Class - The record decl of the class that the base is a base of.
|
||||||
CXXRecordDecl *Class;
|
const CXXRecordDecl *Class;
|
||||||
|
|
||||||
/// SubobjectNumber - Identifies which base class subobject (of type
|
/// SubobjectNumber - Identifies which base class subobject (of type
|
||||||
/// @c Base->getType()) this base path element refers to. This
|
/// @c Base->getType()) this base path element refers to. This
|
||||||
|
|
|
@ -1584,17 +1584,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
||||||
return QualCK;
|
return QualCK;
|
||||||
|
|
||||||
if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
|
if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
|
||||||
|
QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr);
|
||||||
|
QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
|
||||||
// C++0x [over.ics.rank]p3b4:
|
// C++0x [over.ics.rank]p3b4:
|
||||||
// -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
|
// -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
|
||||||
// implicit object parameter of a non-static member function declared
|
// implicit object parameter of a non-static member function declared
|
||||||
// without a ref-qualifier, and S1 binds an rvalue reference to an
|
// without a ref-qualifier, and S1 binds an rvalue reference to an
|
||||||
// rvalue and S2 binds an lvalue reference.
|
// rvalue and S2 binds an lvalue reference.
|
||||||
// FIXME: We don't know if we're dealing with the implicit object parameter,
|
// FIXME: We have far too little information for this check. We don't know
|
||||||
// or if the member function in this case has a ref qualifier.
|
// if the bound object is an rvalue. We don't know if the binding type is
|
||||||
// (Of course, we don't have ref qualifiers yet.)
|
// an rvalue or lvalue reference. We don't know if we're dealing with the
|
||||||
if (SCS1.RRefBinding != SCS2.RRefBinding)
|
// implicit object parameter, or if the member function in this case has
|
||||||
return SCS1.RRefBinding ? ImplicitConversionSequence::Better
|
// a ref qualifier.
|
||||||
: ImplicitConversionSequence::Worse;
|
|
||||||
|
|
||||||
// C++ [over.ics.rank]p3b4:
|
// C++ [over.ics.rank]p3b4:
|
||||||
// -- S1 and S2 are reference bindings (8.5.3), and the types to
|
// -- S1 and S2 are reference bindings (8.5.3), and the types to
|
||||||
|
@ -1602,8 +1603,6 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
||||||
// top-level cv-qualifiers, and the type to which the reference
|
// top-level cv-qualifiers, and the type to which the reference
|
||||||
// initialized by S2 refers is more cv-qualified than the type
|
// initialized by S2 refers is more cv-qualified than the type
|
||||||
// to which the reference initialized by S1 refers.
|
// to which the reference initialized by S1 refers.
|
||||||
QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr);
|
|
||||||
QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
|
|
||||||
T1 = Context.getCanonicalType(T1);
|
T1 = Context.getCanonicalType(T1);
|
||||||
T2 = Context.getCanonicalType(T2);
|
T2 = Context.getCanonicalType(T2);
|
||||||
if (T1.getUnqualifiedType() == T2.getUnqualifiedType()) {
|
if (T1.getUnqualifiedType() == T2.getUnqualifiedType()) {
|
||||||
|
|
|
@ -114,10 +114,6 @@ namespace clang {
|
||||||
/// direct binding (C++ [dcl.init.ref]).
|
/// direct binding (C++ [dcl.init.ref]).
|
||||||
bool DirectBinding : 1;
|
bool DirectBinding : 1;
|
||||||
|
|
||||||
/// RRefBinding - True when this is a reference binding of an rvalue
|
|
||||||
/// reference to an rvalue (C++0x [over.ics.rank]p3b4).
|
|
||||||
bool RRefBinding : 1;
|
|
||||||
|
|
||||||
/// FromType - The type that this conversion is converting
|
/// FromType - The type that this conversion is converting
|
||||||
/// from. This is an opaque pointer that can be translated into a
|
/// from. This is an opaque pointer that can be translated into a
|
||||||
/// QualType.
|
/// QualType.
|
||||||
|
|
|
@ -80,35 +80,3 @@ namespace T6 {
|
||||||
A *a = c;
|
A *a = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace T7 {
|
|
||||||
|
|
||||||
class C;
|
|
||||||
class A { };
|
|
||||||
class B : protected A { // expected-note {{'protected' inheritance specifier here}}
|
|
||||||
void f(C *);
|
|
||||||
};
|
|
||||||
|
|
||||||
class C : protected B { // expected-note {{'protected' inheritance specifier here}}
|
|
||||||
void f(C *c) {
|
|
||||||
A* a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void B::f(C *c) {
|
|
||||||
A *a = c; // expected-error {{conversion from 'class T7::C' to inaccessible base class 'class T7::A'}} \
|
|
||||||
expected-error {{incompatible type initializing 'class T7::C *', expected 'class T7::A *'}}
|
|
||||||
}
|
|
||||||
|
|
||||||
class D : private C {
|
|
||||||
void f(D *d) {
|
|
||||||
A *a = d;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void f(B* b) {
|
|
||||||
A *a = b; // expected-error {{conversion from 'class T7::B' to inaccessible base class 'class T7::A'}} \
|
|
||||||
expected-error {{incompatible type initializing 'class T7::B *', expected 'class T7::A *'}}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,15 +37,14 @@ void f() {
|
||||||
not_int ni2 = over(ret_irr());
|
not_int ni2 = over(ret_irr());
|
||||||
|
|
||||||
int i4 = over2(i1);
|
int i4 = over2(i1);
|
||||||
not_int ni3 = over2(0);
|
// not_int ni3 = over2(0); FIXME: this should be well-formed.
|
||||||
|
|
||||||
ilr_c1 vilr1 = i1;
|
ilr_c1 vilr1 = i1;
|
||||||
ilr_c2 vilr2 = i1;
|
ilr_c2 vilr2 = i1;
|
||||||
|
|
||||||
conv_to_not_int_rvalue cnir;
|
conv_to_not_int_rvalue cnir;
|
||||||
not_int &&ni4 = cnir; // expected-error {{rvalue reference cannot bind to lvalue}}
|
not_int &&ni4 = cnir;
|
||||||
not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'struct not_int' cannot be initialized with a value of type 'struct conv_to_not_int_rvalue'}}
|
not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'struct not_int' cannot be initialized with a value of type 'struct conv_to_not_int_rvalue'}}
|
||||||
not_int &&ni6 = conv_to_not_int_rvalue();
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue