aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaAccess.cpp
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2018-12-03 13:29:17 +0000
committerIlya Biryukov <ibiryukov@google.com>2018-12-03 13:29:17 +0000
commitf1822ec431cded5e50b69152346794d79976a8b2 (patch)
tree367d6815eb69d834b7d7236ed170ddc9b5cb6d56 /clang/lib/Sema/SemaAccess.cpp
parent6ef089d21c8853d4623980617f18490ab64c8548 (diff)
downloadllvm-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.cpp29
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;
}