diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 8c8cae2c8c..ac260c2e20 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1616,13 +1616,6 @@ public: FunctionDecl::StorageClass& SC); DeclTy *ActOnConversionDeclarator(CXXConversionDecl *Conversion); - /// SetMemberAccessSpecifier - Set the access specifier of a member. - /// Returns true on error (when the previous member decl access specifier - /// is different from the new member decl access specifier). - bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, - NamedDecl *PrevMemberDecl, - AccessSpecifier LexicalAS); - //===--------------------------------------------------------------------===// // C++ Derived Classes // @@ -1652,6 +1645,18 @@ public: SourceLocation Loc, SourceRange Range); std::string getAmbiguousPathsDisplayString(BasePaths &Paths); + //===--------------------------------------------------------------------===// + // C++ Access Control + // + + bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, + NamedDecl *PrevMemberDecl, + AccessSpecifier LexicalAS); + + bool CheckBaseClassAccess(QualType Derived, QualType Base, + BasePaths& Paths, SourceLocation AccessLoc); + + enum AbstractDiagSelID { AbstractNone = -1, AbstractReturnType, diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 2ac9a539f3..e44ef5f9ea 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1,4 +1,4 @@ -//===---- SemaInherit.cpp - C++ Access Control ------------------*- C++ -*-===// +//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,6 +14,9 @@ #include "Sema.h" using namespace clang; +/// SetMemberAccessSpecifier - Set the access specifier of a member. +/// Returns true on error (when the previous member decl access specifier +/// is different from the new member decl access specifier). bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS) { @@ -37,3 +40,10 @@ bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, MemberDecl->setAccess(PrevMemberDecl->getAccess()); return false; } + +/// CheckBaseClassAccess - Check that a derived class can access its base class +/// and report an error if it can't. [class.access.base] +bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base, + BasePaths& Paths, SourceLocation AccessLoc) { + return false; +} diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp index ce95a1e614..c572f62d61 100644 --- a/lib/Sema/SemaInherit.cpp +++ b/lib/Sema/SemaInherit.cpp @@ -202,7 +202,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class, /// CheckDerivedToBaseConversion - Check whether the Derived-to-Base /// conversion (where Derived and Base are class types) is /// well-formed, meaning that the conversion is unambiguous (and -/// FIXME: that all of the base classes are accessible). Returns true +/// that all of the base classes are accessible). Returns true /// and emits a diagnostic if the code is ill-formed, returns false /// otherwise. Loc is the location where this routine should point to /// if there is an error, and Range is the source range to highlight @@ -214,15 +214,17 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // ambiguous. This is slightly more expensive than checking whether // the Derived to Base conversion exists, because here we need to // explore multiple paths to determine if there is an ambiguity. - BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); assert(DerivationOkay && "Can only be used with a derived-to-base conversion"); (void)DerivationOkay; - if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) - return false; + if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) { + // Check that the base class can be accessed. + return CheckBaseClassAccess(Derived, Base, Paths, Loc); + } // We know that the derived-to-base conversion is ambiguous, and // we're going to produce a diagnostic. Perform the derived-to-base