From: Anders Carlsson Date: Sat, 28 Mar 2009 04:17:27 +0000 (+0000) Subject: Revert Sebastian's rvalue patch (r67870) since it caused test failures in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=14734f7d2a69f9076e8a06954f06d3313063e7f9;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67912 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index e65b050500..cc212434b7 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -55,7 +55,7 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base, const CXXBaseSpecifier *InacessibleBase = 0; - CXXRecordDecl* CurrentClassDecl = 0; + const CXXRecordDecl* CurrentClassDecl = 0; if (CXXMethodDecl *MD = dyn_cast_or_null(getCurFunctionDecl())) CurrentClassDecl = MD->getParent(); @@ -79,21 +79,9 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base, if (CurrentClassDecl != Element->Class) FoundInaccessibleBase = true; break; - case AS_protected: - // FIXME: Check if the current function/class is a friend. - if (!CurrentClassDecl) { - 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; - } + case AS_protected: + // FIXME: Implement + break; } if (FoundInaccessibleBase) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d4efb085d5..90983040b5 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1970,18 +1970,6 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, // -- 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; // -- is an lvalue (but is not a bit-field), and “cv1 T1” is // reference-compatible with “cv2 T2,” or @@ -1992,6 +1980,14 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, RefRelationship >= Ref_Compatible_With_Added_Qualification) { 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) { // C++ [over.ics.ref]p1: // 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.ReferenceBinding = true; ICS->Standard.DirectBinding = true; - ICS->Standard.RRefBinding = false; // Nothing more to do: the inaccessibility/ambiguity check for // 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 - // type (i.e., cv1 shall be const), or the reference shall be an - // rvalue reference and the initializer expression shall be an rvalue. + // type (i.e., cv1 shall be const), or shall be an rvalue reference. if (!isRValRef && T1.getCVRQualifiers() != QualType::Const) { if (!ICS) Diag(Init->getSourceRange().getBegin(), @@ -2146,7 +2140,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, // shall be callable whether or not the copy is actually // 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 // a temporary in this case. FIXME: We will, however, have to check // 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.ToTypePtr = T1.getAsOpaquePtr(); ICS->Standard.ReferenceBinding = true; - ICS->Standard.DirectBinding = false; - ICS->Standard.RRefBinding = isRValRef; + ICS->Standard.DirectBinding = false; } else { // FIXME: Binding to a subobject of the rvalue is going to require // more AST annotation than this. @@ -2206,27 +2199,18 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, // Actually try to convert the initializer to T1. if (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 - // underlying type of the reference according to - // 13.3.3.1. Conceptually, this conversion sequence corresponds - // to copy-initializing a temporary of the underlying type with - // the argument expression. Any difference in top-level - // cv-qualification is subsumed by the initialization itself - // and does not constitute a conversion. + /// 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 + /// underlying type of the reference according to + /// 13.3.3.1. Conceptually, this conversion sequence corresponds + /// to copy-initializing a temporary of the underlying type with + /// the argument expression. Any difference in top-level + /// cv-qualification is subsumed by the initialization itself + /// and does not constitute a conversion. *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; } else { return PerformImplicitConversion(Init, T1, "initializing"); diff --git a/lib/Sema/SemaInherit.h b/lib/Sema/SemaInherit.h index a164d43e8a..6138685b26 100644 --- a/lib/Sema/SemaInherit.h +++ b/lib/Sema/SemaInherit.h @@ -40,7 +40,7 @@ namespace clang { const CXXBaseSpecifier *Base; /// 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 /// @c Base->getType()) this base path element refers to. This diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 08c3ce9e5a..025a245c6c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1584,17 +1584,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1, return QualCK; if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) { + QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr); + QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); // C++0x [over.ics.rank]p3b4: // -- S1 and S2 are reference bindings (8.5.3) and neither refers to an // implicit object parameter of a non-static member function declared // without a ref-qualifier, and S1 binds an rvalue reference to an // rvalue and S2 binds an lvalue reference. - // FIXME: We don't know if we're dealing with the implicit object parameter, - // or if the member function in this case has a ref qualifier. - // (Of course, we don't have ref qualifiers yet.) - if (SCS1.RRefBinding != SCS2.RRefBinding) - return SCS1.RRefBinding ? ImplicitConversionSequence::Better - : ImplicitConversionSequence::Worse; + // FIXME: We have far too little information for this check. We don't know + // if the bound object is an rvalue. We don't know if the binding type is + // an rvalue or lvalue reference. We don't know if we're dealing with the + // implicit object parameter, or if the member function in this case has + // a ref qualifier. // C++ [over.ics.rank]p3b4: // -- 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 // initialized by S2 refers is more cv-qualified than the type // to which the reference initialized by S1 refers. - QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr); - QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); T1 = Context.getCanonicalType(T1); T2 = Context.getCanonicalType(T2); if (T1.getUnqualifiedType() == T2.getUnqualifiedType()) { diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h index e8fad6f01b..3da8eca1a5 100644 --- a/lib/Sema/SemaOverload.h +++ b/lib/Sema/SemaOverload.h @@ -114,10 +114,6 @@ namespace clang { /// direct binding (C++ [dcl.init.ref]). 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 /// from. This is an opaque pointer that can be translated into a /// QualType. diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp index 3e50b26e5a..f98437695e 100644 --- a/test/SemaCXX/access-base-class.cpp +++ b/test/SemaCXX/access-base-class.cpp @@ -80,35 +80,3 @@ namespace T6 { 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 *'}} -} - -} diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp index 569693a49b..d3057602a0 100644 --- a/test/SemaCXX/rval-references.cpp +++ b/test/SemaCXX/rval-references.cpp @@ -37,15 +37,14 @@ void f() { not_int ni2 = over(ret_irr()); 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_c2 vilr2 = i1; 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 &&ni6 = conv_to_not_int_rvalue(); try {