diff options
author | Ilya Biryukov <ibiryukov@google.com> | 2018-12-03 13:29:17 +0000 |
---|---|---|
committer | Ilya Biryukov <ibiryukov@google.com> | 2018-12-03 13:29:17 +0000 |
commit | f1822ec431cded5e50b69152346794d79976a8b2 (patch) | |
tree | 367d6815eb69d834b7d7236ed170ddc9b5cb6d56 /clang/lib/Sema/SemaAccess.cpp | |
parent | 6ef089d21c8853d4623980617f18490ab64c8548 (diff) | |
download | llvm-f1822ec431cded5e50b69152346794d79976a8b2.zip llvm-f1822ec431cded5e50b69152346794d79976a8b2.tar.gz llvm-f1822ec431cded5e50b69152346794d79976a8b2.tar.bz2 |
[CodeComplete] Cleanup access checking in code completion
Summary: Also fixes a crash (see the added 'accessibility-crash.cpp' test).
Reviewers: ioeric, kadircet
Reviewed By: kadircet
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D55124
llvm-svn: 348135
Diffstat (limited to 'clang/lib/Sema/SemaAccess.cpp')
-rw-r--r-- | clang/lib/Sema/SemaAccess.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index cf33231..0432e70 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1877,22 +1877,33 @@ void Sema::CheckLookupAccess(const LookupResult &R) { /// specifiers into account, but no member access expressions and such. /// /// \param Target the declaration to check if it can be accessed -/// \param Ctx the class/context from which to start the search +/// \param NamingClass the class in which the lookup was started. +/// \param BaseType type of the left side of member access expression. +/// \p BaseType and \p NamingClass are used for C++ access control. +/// Depending on the lookup case, they should be set to the following: +/// - lhs.target (member access without a qualifier): +/// \p BaseType and \p NamingClass are both the type of 'lhs'. +/// - lhs.X::target (member access with a qualifier): +/// BaseType is the type of 'lhs', NamingClass is 'X' +/// - X::target (qualified lookup without member access): +/// BaseType is null, NamingClass is 'X'. +/// - target (unqualified lookup). +/// BaseType is null, NamingClass is the parent class of 'target'. /// \return true if the Target is accessible from the Class, false otherwise. -bool Sema::IsSimplyAccessible(NamedDecl *Target, DeclContext *Ctx) { - if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) { - if (!Target->isCXXClassMember()) - return true; - +bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass, + QualType BaseType) { + // Perform the C++ accessibility checks first. + if (Target->isCXXClassMember() && NamingClass) { + if (!getLangOpts().CPlusPlus) + return false; if (Target->getAccess() == AS_public) return true; - QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal(); // The unprivileged access is AS_none as we don't know how the member was // accessed, which is described by the access in DeclAccessPair. // `IsAccessible` will examine the actual access of Target (i.e. // Decl->getAccess()) when calculating the access. - AccessTarget Entity(Context, AccessedEntity::Member, Class, - DeclAccessPair::make(Target, AS_none), qType); + AccessTarget Entity(Context, AccessedEntity::Member, NamingClass, + DeclAccessPair::make(Target, AS_none), BaseType); EffectiveContext EC(CurContext); return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible; } |