[HLSL] Implement RWBuffer::operator[] via __builtin_hlsl_resource_getpointer (#117017)
[llvm-project.git] / clang / lib / Sema / SemaAccess.cpp
blobf79d9a758e7af3bf35a1ac8a202190ac1acb365a
1 //===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides Sema routines for C++ access control semantics.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/CXXInheritance.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/DeclFriend.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DependentDiagnostic.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/Basic/Specifiers.h"
21 #include "clang/Sema/DelayedDiagnostic.h"
22 #include "clang/Sema/Initialization.h"
23 #include "clang/Sema/Lookup.h"
24 #include "llvm/ADT/STLForwardCompat.h"
26 using namespace clang;
27 using namespace sema;
29 /// A copy of Sema's enum without AR_delayed.
30 enum AccessResult {
31 AR_accessible,
32 AR_inaccessible,
33 AR_dependent
36 bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
37 NamedDecl *PrevMemberDecl,
38 AccessSpecifier LexicalAS) {
39 if (!PrevMemberDecl) {
40 // Use the lexical access specifier.
41 MemberDecl->setAccess(LexicalAS);
42 return false;
45 // C++ [class.access.spec]p3: When a member is redeclared its access
46 // specifier must be same as its initial declaration.
47 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
48 Diag(MemberDecl->getLocation(),
49 diag::err_class_redeclared_with_different_access)
50 << MemberDecl << LexicalAS;
51 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
52 << PrevMemberDecl << PrevMemberDecl->getAccess();
54 MemberDecl->setAccess(LexicalAS);
55 return true;
58 MemberDecl->setAccess(PrevMemberDecl->getAccess());
59 return false;
62 static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
63 DeclContext *DC = D->getDeclContext();
65 // This can only happen at top: enum decls only "publish" their
66 // immediate members.
67 if (isa<EnumDecl>(DC))
68 DC = cast<EnumDecl>(DC)->getDeclContext();
70 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
71 while (DeclaringClass->isAnonymousStructOrUnion())
72 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
73 return DeclaringClass;
76 namespace {
77 struct EffectiveContext {
78 EffectiveContext() : Inner(nullptr), Dependent(false) {}
80 explicit EffectiveContext(DeclContext *DC)
81 : Inner(DC),
82 Dependent(DC->isDependentContext()) {
84 // An implicit deduction guide is semantically in the context enclosing the
85 // class template, but for access purposes behaves like the constructor
86 // from which it was produced.
87 if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
88 if (DGD->isImplicit()) {
89 DC = DGD->getCorrespondingConstructor();
90 if (!DC) {
91 // The copy deduction candidate doesn't have a corresponding
92 // constructor.
93 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
98 // C++11 [class.access.nest]p1:
99 // A nested class is a member and as such has the same access
100 // rights as any other member.
101 // C++11 [class.access]p2:
102 // A member of a class can also access all the names to which
103 // the class has access. A local class of a member function
104 // may access the same names that the member function itself
105 // may access.
106 // This almost implies that the privileges of nesting are transitive.
107 // Technically it says nothing about the local classes of non-member
108 // functions (which can gain privileges through friendship), but we
109 // take that as an oversight.
110 while (true) {
111 // We want to add canonical declarations to the EC lists for
112 // simplicity of checking, but we need to walk up through the
113 // actual current DC chain. Otherwise, something like a local
114 // extern or friend which happens to be the canonical
115 // declaration will really mess us up.
117 if (isa<CXXRecordDecl>(DC)) {
118 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
119 Records.push_back(Record->getCanonicalDecl());
120 DC = Record->getDeclContext();
121 } else if (isa<FunctionDecl>(DC)) {
122 FunctionDecl *Function = cast<FunctionDecl>(DC);
123 Functions.push_back(Function->getCanonicalDecl());
124 if (Function->getFriendObjectKind())
125 DC = Function->getLexicalDeclContext();
126 else
127 DC = Function->getDeclContext();
128 } else if (DC->isFileContext()) {
129 break;
130 } else {
131 DC = DC->getParent();
136 bool isDependent() const { return Dependent; }
138 bool includesClass(const CXXRecordDecl *R) const {
139 R = R->getCanonicalDecl();
140 return llvm::is_contained(Records, R);
143 /// Retrieves the innermost "useful" context. Can be null if we're
144 /// doing access-control without privileges.
145 DeclContext *getInnerContext() const {
146 return Inner;
149 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
151 DeclContext *Inner;
152 SmallVector<FunctionDecl*, 4> Functions;
153 SmallVector<CXXRecordDecl*, 4> Records;
154 bool Dependent;
157 /// Like sema::AccessedEntity, but kindly lets us scribble all over
158 /// it.
159 struct AccessTarget : public AccessedEntity {
160 AccessTarget(const AccessedEntity &Entity)
161 : AccessedEntity(Entity) {
162 initialize();
165 AccessTarget(ASTContext &Context,
166 MemberNonce _,
167 CXXRecordDecl *NamingClass,
168 DeclAccessPair FoundDecl,
169 QualType BaseObjectType)
170 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
171 FoundDecl, BaseObjectType) {
172 initialize();
175 AccessTarget(ASTContext &Context,
176 BaseNonce _,
177 CXXRecordDecl *BaseClass,
178 CXXRecordDecl *DerivedClass,
179 AccessSpecifier Access)
180 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
181 Access) {
182 initialize();
185 bool isInstanceMember() const {
186 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
189 bool hasInstanceContext() const {
190 return HasInstanceContext;
193 class SavedInstanceContext {
194 public:
195 SavedInstanceContext(SavedInstanceContext &&S)
196 : Target(S.Target), Has(S.Has) {
197 S.Target = nullptr;
200 // The move assignment operator is defined as deleted pending further
201 // motivation.
202 SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;
204 // The copy constrcutor and copy assignment operator is defined as deleted
205 // pending further motivation.
206 SavedInstanceContext(const SavedInstanceContext &) = delete;
207 SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;
209 ~SavedInstanceContext() {
210 if (Target)
211 Target->HasInstanceContext = Has;
214 private:
215 friend struct AccessTarget;
216 explicit SavedInstanceContext(AccessTarget &Target)
217 : Target(&Target), Has(Target.HasInstanceContext) {}
218 AccessTarget *Target;
219 bool Has;
222 SavedInstanceContext saveInstanceContext() {
223 return SavedInstanceContext(*this);
226 void suppressInstanceContext() {
227 HasInstanceContext = false;
230 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
231 assert(HasInstanceContext);
232 if (CalculatedInstanceContext)
233 return InstanceContext;
235 CalculatedInstanceContext = true;
236 DeclContext *IC = S.computeDeclContext(getBaseObjectType());
237 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
238 : nullptr);
239 return InstanceContext;
242 const CXXRecordDecl *getDeclaringClass() const {
243 return DeclaringClass;
246 /// The "effective" naming class is the canonical non-anonymous
247 /// class containing the actual naming class.
248 const CXXRecordDecl *getEffectiveNamingClass() const {
249 const CXXRecordDecl *namingClass = getNamingClass();
250 while (namingClass->isAnonymousStructOrUnion())
251 namingClass = cast<CXXRecordDecl>(namingClass->getParent());
252 return namingClass->getCanonicalDecl();
255 private:
256 void initialize() {
257 HasInstanceContext = (isMemberAccess() &&
258 !getBaseObjectType().isNull() &&
259 getTargetDecl()->isCXXInstanceMember());
260 CalculatedInstanceContext = false;
261 InstanceContext = nullptr;
263 if (isMemberAccess())
264 DeclaringClass = FindDeclaringClass(getTargetDecl());
265 else
266 DeclaringClass = getBaseClass();
267 DeclaringClass = DeclaringClass->getCanonicalDecl();
270 bool HasInstanceContext : 1;
271 mutable bool CalculatedInstanceContext : 1;
272 mutable const CXXRecordDecl *InstanceContext;
273 const CXXRecordDecl *DeclaringClass;
278 /// Checks whether one class might instantiate to the other.
279 static bool MightInstantiateTo(const CXXRecordDecl *From,
280 const CXXRecordDecl *To) {
281 // Declaration names are always preserved by instantiation.
282 if (From->getDeclName() != To->getDeclName())
283 return false;
285 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
286 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
287 if (FromDC == ToDC) return true;
288 if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
290 // Be conservative.
291 return true;
294 /// Checks whether one class is derived from another, inclusively.
295 /// Properly indicates when it couldn't be determined due to
296 /// dependence.
298 /// This should probably be donated to AST or at least Sema.
299 static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
300 const CXXRecordDecl *Target) {
301 assert(Derived->getCanonicalDecl() == Derived);
302 assert(Target->getCanonicalDecl() == Target);
304 if (Derived == Target) return AR_accessible;
306 bool CheckDependent = Derived->isDependentContext();
307 if (CheckDependent && MightInstantiateTo(Derived, Target))
308 return AR_dependent;
310 AccessResult OnFailure = AR_inaccessible;
311 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
313 while (true) {
314 if (Derived->isDependentContext() && !Derived->hasDefinition() &&
315 !Derived->isLambda())
316 return AR_dependent;
318 for (const auto &I : Derived->bases()) {
319 const CXXRecordDecl *RD;
321 QualType T = I.getType();
322 if (const RecordType *RT = T->getAs<RecordType>()) {
323 RD = cast<CXXRecordDecl>(RT->getDecl());
324 } else if (const InjectedClassNameType *IT
325 = T->getAs<InjectedClassNameType>()) {
326 RD = IT->getDecl();
327 } else {
328 assert(T->isDependentType() && "non-dependent base wasn't a record?");
329 OnFailure = AR_dependent;
330 continue;
333 RD = RD->getCanonicalDecl();
334 if (RD == Target) return AR_accessible;
335 if (CheckDependent && MightInstantiateTo(RD, Target))
336 OnFailure = AR_dependent;
338 Queue.push_back(RD);
341 if (Queue.empty()) break;
343 Derived = Queue.pop_back_val();
346 return OnFailure;
350 static bool MightInstantiateTo(Sema &S, DeclContext *Context,
351 DeclContext *Friend) {
352 if (Friend == Context)
353 return true;
355 assert(!Friend->isDependentContext() &&
356 "can't handle friends with dependent contexts here");
358 if (!Context->isDependentContext())
359 return false;
361 if (Friend->isFileContext())
362 return false;
364 // TODO: this is very conservative
365 return true;
368 // Asks whether the type in 'context' can ever instantiate to the type
369 // in 'friend'.
370 static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
371 if (Friend == Context)
372 return true;
374 if (!Friend->isDependentType() && !Context->isDependentType())
375 return false;
377 // TODO: this is very conservative.
378 return true;
381 static bool MightInstantiateTo(Sema &S,
382 FunctionDecl *Context,
383 FunctionDecl *Friend) {
384 if (Context->getDeclName() != Friend->getDeclName())
385 return false;
387 if (!MightInstantiateTo(S,
388 Context->getDeclContext(),
389 Friend->getDeclContext()))
390 return false;
392 CanQual<FunctionProtoType> FriendTy
393 = S.Context.getCanonicalType(Friend->getType())
394 ->getAs<FunctionProtoType>();
395 CanQual<FunctionProtoType> ContextTy
396 = S.Context.getCanonicalType(Context->getType())
397 ->getAs<FunctionProtoType>();
399 // There isn't any way that I know of to add qualifiers
400 // during instantiation.
401 if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
402 return false;
404 if (FriendTy->getNumParams() != ContextTy->getNumParams())
405 return false;
407 if (!MightInstantiateTo(S, ContextTy->getReturnType(),
408 FriendTy->getReturnType()))
409 return false;
411 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
412 if (!MightInstantiateTo(S, ContextTy->getParamType(I),
413 FriendTy->getParamType(I)))
414 return false;
416 return true;
419 static bool MightInstantiateTo(Sema &S,
420 FunctionTemplateDecl *Context,
421 FunctionTemplateDecl *Friend) {
422 return MightInstantiateTo(S,
423 Context->getTemplatedDecl(),
424 Friend->getTemplatedDecl());
427 static AccessResult MatchesFriend(Sema &S,
428 const EffectiveContext &EC,
429 const CXXRecordDecl *Friend) {
430 if (EC.includesClass(Friend))
431 return AR_accessible;
433 if (EC.isDependent()) {
434 for (const CXXRecordDecl *Context : EC.Records) {
435 if (MightInstantiateTo(Context, Friend))
436 return AR_dependent;
440 return AR_inaccessible;
443 static AccessResult MatchesFriend(Sema &S,
444 const EffectiveContext &EC,
445 CanQualType Friend) {
446 if (const RecordType *RT = Friend->getAs<RecordType>())
447 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
449 // TODO: we can do better than this
450 if (Friend->isDependentType())
451 return AR_dependent;
453 return AR_inaccessible;
456 /// Determines whether the given friend class template matches
457 /// anything in the effective context.
458 static AccessResult MatchesFriend(Sema &S,
459 const EffectiveContext &EC,
460 ClassTemplateDecl *Friend) {
461 AccessResult OnFailure = AR_inaccessible;
463 // Check whether the friend is the template of a class in the
464 // context chain.
465 for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
466 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
467 CXXRecordDecl *Record = *I;
469 // Figure out whether the current class has a template:
470 ClassTemplateDecl *CTD;
472 // A specialization of the template...
473 if (isa<ClassTemplateSpecializationDecl>(Record)) {
474 CTD = cast<ClassTemplateSpecializationDecl>(Record)
475 ->getSpecializedTemplate();
477 // ... or the template pattern itself.
478 } else {
479 CTD = Record->getDescribedClassTemplate();
480 if (!CTD) continue;
483 // It's a match.
484 if (Friend == CTD->getCanonicalDecl())
485 return AR_accessible;
487 // If the context isn't dependent, it can't be a dependent match.
488 if (!EC.isDependent())
489 continue;
491 // If the template names don't match, it can't be a dependent
492 // match.
493 if (CTD->getDeclName() != Friend->getDeclName())
494 continue;
496 // If the class's context can't instantiate to the friend's
497 // context, it can't be a dependent match.
498 if (!MightInstantiateTo(S, CTD->getDeclContext(),
499 Friend->getDeclContext()))
500 continue;
502 // Otherwise, it's a dependent match.
503 OnFailure = AR_dependent;
506 return OnFailure;
509 /// Determines whether the given friend function matches anything in
510 /// the effective context.
511 static AccessResult MatchesFriend(Sema &S,
512 const EffectiveContext &EC,
513 FunctionDecl *Friend) {
514 AccessResult OnFailure = AR_inaccessible;
516 for (SmallVectorImpl<FunctionDecl*>::const_iterator
517 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
518 if (Friend == *I)
519 return AR_accessible;
521 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
522 OnFailure = AR_dependent;
525 return OnFailure;
528 /// Determines whether the given friend function template matches
529 /// anything in the effective context.
530 static AccessResult MatchesFriend(Sema &S,
531 const EffectiveContext &EC,
532 FunctionTemplateDecl *Friend) {
533 if (EC.Functions.empty()) return AR_inaccessible;
535 AccessResult OnFailure = AR_inaccessible;
537 for (SmallVectorImpl<FunctionDecl*>::const_iterator
538 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
540 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
541 if (!FTD)
542 FTD = (*I)->getDescribedFunctionTemplate();
543 if (!FTD)
544 continue;
546 FTD = FTD->getCanonicalDecl();
548 if (Friend == FTD)
549 return AR_accessible;
551 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
552 OnFailure = AR_dependent;
555 return OnFailure;
558 /// Determines whether the given friend declaration matches anything
559 /// in the effective context.
560 static AccessResult MatchesFriend(Sema &S,
561 const EffectiveContext &EC,
562 FriendDecl *FriendD) {
563 // Whitelist accesses if there's an invalid or unsupported friend
564 // declaration.
565 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
566 return AR_accessible;
568 if (TypeSourceInfo *T = FriendD->getFriendType())
569 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
571 NamedDecl *Friend
572 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
574 // FIXME: declarations with dependent or templated scope.
576 if (isa<ClassTemplateDecl>(Friend))
577 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
579 if (isa<FunctionTemplateDecl>(Friend))
580 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
582 if (isa<CXXRecordDecl>(Friend))
583 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
585 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
586 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
589 static AccessResult GetFriendKind(Sema &S,
590 const EffectiveContext &EC,
591 const CXXRecordDecl *Class) {
592 AccessResult OnFailure = AR_inaccessible;
594 // Okay, check friends.
595 for (auto *Friend : Class->friends()) {
596 switch (MatchesFriend(S, EC, Friend)) {
597 case AR_accessible:
598 return AR_accessible;
600 case AR_inaccessible:
601 continue;
603 case AR_dependent:
604 OnFailure = AR_dependent;
605 break;
609 // That's it, give up.
610 return OnFailure;
613 namespace {
615 /// A helper class for checking for a friend which will grant access
616 /// to a protected instance member.
617 struct ProtectedFriendContext {
618 Sema &S;
619 const EffectiveContext &EC;
620 const CXXRecordDecl *NamingClass;
621 bool CheckDependent;
622 bool EverDependent;
624 /// The path down to the current base class.
625 SmallVector<const CXXRecordDecl*, 20> CurPath;
627 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
628 const CXXRecordDecl *InstanceContext,
629 const CXXRecordDecl *NamingClass)
630 : S(S), EC(EC), NamingClass(NamingClass),
631 CheckDependent(InstanceContext->isDependentContext() ||
632 NamingClass->isDependentContext()),
633 EverDependent(false) {}
635 /// Check classes in the current path for friendship, starting at
636 /// the given index.
637 bool checkFriendshipAlongPath(unsigned I) {
638 assert(I < CurPath.size());
639 for (unsigned E = CurPath.size(); I != E; ++I) {
640 switch (GetFriendKind(S, EC, CurPath[I])) {
641 case AR_accessible: return true;
642 case AR_inaccessible: continue;
643 case AR_dependent: EverDependent = true; continue;
646 return false;
649 /// Perform a search starting at the given class.
651 /// PrivateDepth is the index of the last (least derived) class
652 /// along the current path such that a notional public member of
653 /// the final class in the path would have access in that class.
654 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
655 // If we ever reach the naming class, check the current path for
656 // friendship. We can also stop recursing because we obviously
657 // won't find the naming class there again.
658 if (Cur == NamingClass)
659 return checkFriendshipAlongPath(PrivateDepth);
661 if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
662 EverDependent = true;
664 // Recurse into the base classes.
665 for (const auto &I : Cur->bases()) {
666 // If this is private inheritance, then a public member of the
667 // base will not have any access in classes derived from Cur.
668 unsigned BasePrivateDepth = PrivateDepth;
669 if (I.getAccessSpecifier() == AS_private)
670 BasePrivateDepth = CurPath.size() - 1;
672 const CXXRecordDecl *RD;
674 QualType T = I.getType();
675 if (const RecordType *RT = T->getAs<RecordType>()) {
676 RD = cast<CXXRecordDecl>(RT->getDecl());
677 } else if (const InjectedClassNameType *IT
678 = T->getAs<InjectedClassNameType>()) {
679 RD = IT->getDecl();
680 } else {
681 assert(T->isDependentType() && "non-dependent base wasn't a record?");
682 EverDependent = true;
683 continue;
686 // Recurse. We don't need to clean up if this returns true.
687 CurPath.push_back(RD);
688 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
689 return true;
690 CurPath.pop_back();
693 return false;
696 bool findFriendship(const CXXRecordDecl *Cur) {
697 assert(CurPath.empty());
698 CurPath.push_back(Cur);
699 return findFriendship(Cur, 0);
704 /// Search for a class P that EC is a friend of, under the constraint
705 /// InstanceContext <= P
706 /// if InstanceContext exists, or else
707 /// NamingClass <= P
708 /// and with the additional restriction that a protected member of
709 /// NamingClass would have some natural access in P, which implicitly
710 /// imposes the constraint that P <= NamingClass.
712 /// This isn't quite the condition laid out in the standard.
713 /// Instead of saying that a notional protected member of NamingClass
714 /// would have to have some natural access in P, it says the actual
715 /// target has to have some natural access in P, which opens up the
716 /// possibility that the target (which is not necessarily a member
717 /// of NamingClass) might be more accessible along some path not
718 /// passing through it. That's really a bad idea, though, because it
719 /// introduces two problems:
720 /// - Most importantly, it breaks encapsulation because you can
721 /// access a forbidden base class's members by directly subclassing
722 /// it elsewhere.
723 /// - It also makes access substantially harder to compute because it
724 /// breaks the hill-climbing algorithm: knowing that the target is
725 /// accessible in some base class would no longer let you change
726 /// the question solely to whether the base class is accessible,
727 /// because the original target might have been more accessible
728 /// because of crazy subclassing.
729 /// So we don't implement that.
730 static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
731 const CXXRecordDecl *InstanceContext,
732 const CXXRecordDecl *NamingClass) {
733 assert(InstanceContext == nullptr ||
734 InstanceContext->getCanonicalDecl() == InstanceContext);
735 assert(NamingClass->getCanonicalDecl() == NamingClass);
737 // If we don't have an instance context, our constraints give us
738 // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
739 // This is just the usual friendship check.
740 if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
742 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
743 if (PRC.findFriendship(InstanceContext)) return AR_accessible;
744 if (PRC.EverDependent) return AR_dependent;
745 return AR_inaccessible;
748 static AccessResult HasAccess(Sema &S,
749 const EffectiveContext &EC,
750 const CXXRecordDecl *NamingClass,
751 AccessSpecifier Access,
752 const AccessTarget &Target) {
753 assert(NamingClass->getCanonicalDecl() == NamingClass &&
754 "declaration should be canonicalized before being passed here");
756 if (Access == AS_public) return AR_accessible;
757 assert(Access == AS_private || Access == AS_protected);
759 AccessResult OnFailure = AR_inaccessible;
761 for (EffectiveContext::record_iterator
762 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
763 // All the declarations in EC have been canonicalized, so pointer
764 // equality from this point on will work fine.
765 const CXXRecordDecl *ECRecord = *I;
767 // [B2] and [M2]
768 if (Access == AS_private) {
769 if (ECRecord == NamingClass)
770 return AR_accessible;
772 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
773 OnFailure = AR_dependent;
775 // [B3] and [M3]
776 } else {
777 assert(Access == AS_protected);
778 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
779 case AR_accessible: break;
780 case AR_inaccessible: continue;
781 case AR_dependent: OnFailure = AR_dependent; continue;
784 // C++ [class.protected]p1:
785 // An additional access check beyond those described earlier in
786 // [class.access] is applied when a non-static data member or
787 // non-static member function is a protected member of its naming
788 // class. As described earlier, access to a protected member is
789 // granted because the reference occurs in a friend or member of
790 // some class C. If the access is to form a pointer to member,
791 // the nested-name-specifier shall name C or a class derived from
792 // C. All other accesses involve a (possibly implicit) object
793 // expression. In this case, the class of the object expression
794 // shall be C or a class derived from C.
796 // We interpret this as a restriction on [M3].
798 // In this part of the code, 'C' is just our context class ECRecord.
800 // These rules are different if we don't have an instance context.
801 if (!Target.hasInstanceContext()) {
802 // If it's not an instance member, these restrictions don't apply.
803 if (!Target.isInstanceMember()) return AR_accessible;
805 // If it's an instance member, use the pointer-to-member rule
806 // that the naming class has to be derived from the effective
807 // context.
809 // Emulate a MSVC bug where the creation of pointer-to-member
810 // to protected member of base class is allowed but only from
811 // static member functions.
812 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
813 if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
814 if (MD->isStatic()) return AR_accessible;
816 // Despite the standard's confident wording, there is a case
817 // where you can have an instance member that's neither in a
818 // pointer-to-member expression nor in a member access: when
819 // it names a field in an unevaluated context that can't be an
820 // implicit member. Pending clarification, we just apply the
821 // same naming-class restriction here.
822 // FIXME: we're probably not correctly adding the
823 // protected-member restriction when we retroactively convert
824 // an expression to being evaluated.
826 // We know that ECRecord derives from NamingClass. The
827 // restriction says to check whether NamingClass derives from
828 // ECRecord, but that's not really necessary: two distinct
829 // classes can't be recursively derived from each other. So
830 // along this path, we just need to check whether the classes
831 // are equal.
832 if (NamingClass == ECRecord) return AR_accessible;
834 // Otherwise, this context class tells us nothing; on to the next.
835 continue;
838 assert(Target.isInstanceMember());
840 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
841 if (!InstanceContext) {
842 OnFailure = AR_dependent;
843 continue;
846 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
847 case AR_accessible: return AR_accessible;
848 case AR_inaccessible: continue;
849 case AR_dependent: OnFailure = AR_dependent; continue;
854 // [M3] and [B3] say that, if the target is protected in N, we grant
855 // access if the access occurs in a friend or member of some class P
856 // that's a subclass of N and where the target has some natural
857 // access in P. The 'member' aspect is easy to handle because P
858 // would necessarily be one of the effective-context records, and we
859 // address that above. The 'friend' aspect is completely ridiculous
860 // to implement because there are no restrictions at all on P
861 // *unless* the [class.protected] restriction applies. If it does,
862 // however, we should ignore whether the naming class is a friend,
863 // and instead rely on whether any potential P is a friend.
864 if (Access == AS_protected && Target.isInstanceMember()) {
865 // Compute the instance context if possible.
866 const CXXRecordDecl *InstanceContext = nullptr;
867 if (Target.hasInstanceContext()) {
868 InstanceContext = Target.resolveInstanceContext(S);
869 if (!InstanceContext) return AR_dependent;
872 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
873 case AR_accessible: return AR_accessible;
874 case AR_inaccessible: return OnFailure;
875 case AR_dependent: return AR_dependent;
877 llvm_unreachable("impossible friendship kind");
880 switch (GetFriendKind(S, EC, NamingClass)) {
881 case AR_accessible: return AR_accessible;
882 case AR_inaccessible: return OnFailure;
883 case AR_dependent: return AR_dependent;
886 // Silence bogus warnings
887 llvm_unreachable("impossible friendship kind");
890 /// Finds the best path from the naming class to the declaring class,
891 /// taking friend declarations into account.
893 /// C++0x [class.access.base]p5:
894 /// A member m is accessible at the point R when named in class N if
895 /// [M1] m as a member of N is public, or
896 /// [M2] m as a member of N is private, and R occurs in a member or
897 /// friend of class N, or
898 /// [M3] m as a member of N is protected, and R occurs in a member or
899 /// friend of class N, or in a member or friend of a class P
900 /// derived from N, where m as a member of P is public, private,
901 /// or protected, or
902 /// [M4] there exists a base class B of N that is accessible at R, and
903 /// m is accessible at R when named in class B.
905 /// C++0x [class.access.base]p4:
906 /// A base class B of N is accessible at R, if
907 /// [B1] an invented public member of B would be a public member of N, or
908 /// [B2] R occurs in a member or friend of class N, and an invented public
909 /// member of B would be a private or protected member of N, or
910 /// [B3] R occurs in a member or friend of a class P derived from N, and an
911 /// invented public member of B would be a private or protected member
912 /// of P, or
913 /// [B4] there exists a class S such that B is a base class of S accessible
914 /// at R and S is a base class of N accessible at R.
916 /// Along a single inheritance path we can restate both of these
917 /// iteratively:
919 /// First, we note that M1-4 are equivalent to B1-4 if the member is
920 /// treated as a notional base of its declaring class with inheritance
921 /// access equivalent to the member's access. Therefore we need only
922 /// ask whether a class B is accessible from a class N in context R.
924 /// Let B_1 .. B_n be the inheritance path in question (i.e. where
925 /// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
926 /// B_i). For i in 1..n, we will calculate ACAB(i), the access to the
927 /// closest accessible base in the path:
928 /// Access(a, b) = (* access on the base specifier from a to b *)
929 /// Merge(a, forbidden) = forbidden
930 /// Merge(a, private) = forbidden
931 /// Merge(a, b) = min(a,b)
932 /// Accessible(c, forbidden) = false
933 /// Accessible(c, private) = (R is c) || IsFriend(c, R)
934 /// Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
935 /// Accessible(c, public) = true
936 /// ACAB(n) = public
937 /// ACAB(i) =
938 /// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
939 /// if Accessible(B_i, AccessToBase) then public else AccessToBase
941 /// B is an accessible base of N at R iff ACAB(1) = public.
943 /// \param FinalAccess the access of the "final step", or AS_public if
944 /// there is no final step.
945 /// \return null if friendship is dependent
946 static CXXBasePath *FindBestPath(Sema &S,
947 const EffectiveContext &EC,
948 AccessTarget &Target,
949 AccessSpecifier FinalAccess,
950 CXXBasePaths &Paths) {
951 // Derive the paths to the desired base.
952 const CXXRecordDecl *Derived = Target.getNamingClass();
953 const CXXRecordDecl *Base = Target.getDeclaringClass();
955 // FIXME: fail correctly when there are dependent paths.
956 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
957 Paths);
958 assert(isDerived && "derived class not actually derived from base");
959 (void) isDerived;
961 CXXBasePath *BestPath = nullptr;
963 assert(FinalAccess != AS_none && "forbidden access after declaring class");
965 bool AnyDependent = false;
967 // Derive the friend-modified access along each path.
968 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
969 PI != PE; ++PI) {
970 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
972 // Walk through the path backwards.
973 AccessSpecifier PathAccess = FinalAccess;
974 CXXBasePath::iterator I = PI->end(), E = PI->begin();
975 while (I != E) {
976 --I;
978 assert(PathAccess != AS_none);
980 // If the declaration is a private member of a base class, there
981 // is no level of friendship in derived classes that can make it
982 // accessible.
983 if (PathAccess == AS_private) {
984 PathAccess = AS_none;
985 break;
988 const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
990 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
991 PathAccess = std::max(PathAccess, BaseAccess);
993 switch (HasAccess(S, EC, NC, PathAccess, Target)) {
994 case AR_inaccessible: break;
995 case AR_accessible:
996 PathAccess = AS_public;
998 // Future tests are not against members and so do not have
999 // instance context.
1000 Target.suppressInstanceContext();
1001 break;
1002 case AR_dependent:
1003 AnyDependent = true;
1004 goto Next;
1008 // Note that we modify the path's Access field to the
1009 // friend-modified access.
1010 if (BestPath == nullptr || PathAccess < BestPath->Access) {
1011 BestPath = &*PI;
1012 BestPath->Access = PathAccess;
1014 // Short-circuit if we found a public path.
1015 if (BestPath->Access == AS_public)
1016 return BestPath;
1019 Next: ;
1022 assert((!BestPath || BestPath->Access != AS_public) &&
1023 "fell out of loop with public path");
1025 // We didn't find a public path, but at least one path was subject
1026 // to dependent friendship, so delay the check.
1027 if (AnyDependent)
1028 return nullptr;
1030 return BestPath;
1033 /// Given that an entity has protected natural access, check whether
1034 /// access might be denied because of the protected member access
1035 /// restriction.
1037 /// \return true if a note was emitted
1038 static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1039 AccessTarget &Target) {
1040 // Only applies to instance accesses.
1041 if (!Target.isInstanceMember())
1042 return false;
1044 assert(Target.isMemberAccess());
1046 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1048 for (EffectiveContext::record_iterator
1049 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1050 const CXXRecordDecl *ECRecord = *I;
1051 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1052 case AR_accessible: break;
1053 case AR_inaccessible: continue;
1054 case AR_dependent: continue;
1057 // The effective context is a subclass of the declaring class.
1058 // Check whether the [class.protected] restriction is limiting
1059 // access.
1061 // To get this exactly right, this might need to be checked more
1062 // holistically; it's not necessarily the case that gaining
1063 // access here would grant us access overall.
1065 NamedDecl *D = Target.getTargetDecl();
1067 // If we don't have an instance context, [class.protected] says the
1068 // naming class has to equal the context class.
1069 if (!Target.hasInstanceContext()) {
1070 // If it does, the restriction doesn't apply.
1071 if (NamingClass == ECRecord) continue;
1073 // TODO: it would be great to have a fixit here, since this is
1074 // such an obvious error.
1075 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1076 << S.Context.getTypeDeclType(ECRecord);
1077 return true;
1080 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1081 assert(InstanceContext && "diagnosing dependent access");
1083 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1084 case AR_accessible: continue;
1085 case AR_dependent: continue;
1086 case AR_inaccessible:
1087 break;
1090 // Okay, the restriction seems to be what's limiting us.
1092 // Use a special diagnostic for constructors and destructors.
1093 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1094 (isa<FunctionTemplateDecl>(D) &&
1095 isa<CXXConstructorDecl>(
1096 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1097 return S.Diag(D->getLocation(),
1098 diag::note_access_protected_restricted_ctordtor)
1099 << isa<CXXDestructorDecl>(D->getAsFunction());
1102 // Otherwise, use the generic diagnostic.
1103 return S.Diag(D->getLocation(),
1104 diag::note_access_protected_restricted_object)
1105 << S.Context.getTypeDeclType(ECRecord);
1108 return false;
1111 /// We are unable to access a given declaration due to its direct
1112 /// access control; diagnose that.
1113 static void diagnoseBadDirectAccess(Sema &S,
1114 const EffectiveContext &EC,
1115 AccessTarget &entity) {
1116 assert(entity.isMemberAccess());
1117 NamedDecl *D = entity.getTargetDecl();
1119 if (D->getAccess() == AS_protected &&
1120 TryDiagnoseProtectedAccess(S, EC, entity))
1121 return;
1123 // Find an original declaration.
1124 while (D->isOutOfLine()) {
1125 NamedDecl *PrevDecl = nullptr;
1126 if (VarDecl *VD = dyn_cast<VarDecl>(D))
1127 PrevDecl = VD->getPreviousDecl();
1128 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1129 PrevDecl = FD->getPreviousDecl();
1130 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1131 PrevDecl = TND->getPreviousDecl();
1132 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1133 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1134 break;
1135 PrevDecl = TD->getPreviousDecl();
1137 if (!PrevDecl) break;
1138 D = PrevDecl;
1141 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1142 Decl *ImmediateChild;
1143 if (D->getDeclContext() == DeclaringClass)
1144 ImmediateChild = D;
1145 else {
1146 DeclContext *DC = D->getDeclContext();
1147 while (DC->getParent() != DeclaringClass)
1148 DC = DC->getParent();
1149 ImmediateChild = cast<Decl>(DC);
1152 // Check whether there's an AccessSpecDecl preceding this in the
1153 // chain of the DeclContext.
1154 bool isImplicit = true;
1155 for (const auto *I : DeclaringClass->decls()) {
1156 if (I == ImmediateChild) break;
1157 if (isa<AccessSpecDecl>(I)) {
1158 isImplicit = false;
1159 break;
1163 S.Diag(D->getLocation(), diag::note_access_natural)
1164 << (unsigned) (D->getAccess() == AS_protected)
1165 << isImplicit;
1168 /// Diagnose the path which caused the given declaration or base class
1169 /// to become inaccessible.
1170 static void DiagnoseAccessPath(Sema &S,
1171 const EffectiveContext &EC,
1172 AccessTarget &entity) {
1173 // Save the instance context to preserve invariants.
1174 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1176 // This basically repeats the main algorithm but keeps some more
1177 // information.
1179 // The natural access so far.
1180 AccessSpecifier accessSoFar = AS_public;
1182 // Check whether we have special rights to the declaring class.
1183 if (entity.isMemberAccess()) {
1184 NamedDecl *D = entity.getTargetDecl();
1185 accessSoFar = D->getAccess();
1186 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1188 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1189 // If the declaration is accessible when named in its declaring
1190 // class, then we must be constrained by the path.
1191 case AR_accessible:
1192 accessSoFar = AS_public;
1193 entity.suppressInstanceContext();
1194 break;
1196 case AR_inaccessible:
1197 if (accessSoFar == AS_private ||
1198 declaringClass == entity.getEffectiveNamingClass())
1199 return diagnoseBadDirectAccess(S, EC, entity);
1200 break;
1202 case AR_dependent:
1203 llvm_unreachable("cannot diagnose dependent access");
1207 CXXBasePaths paths;
1208 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1209 assert(path.Access != AS_public);
1211 CXXBasePath::iterator i = path.end(), e = path.begin();
1212 CXXBasePath::iterator constrainingBase = i;
1213 while (i != e) {
1214 --i;
1216 assert(accessSoFar != AS_none && accessSoFar != AS_private);
1218 // Is the entity accessible when named in the deriving class, as
1219 // modified by the base specifier?
1220 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1221 const CXXBaseSpecifier *base = i->Base;
1223 // If the access to this base is worse than the access we have to
1224 // the declaration, remember it.
1225 AccessSpecifier baseAccess = base->getAccessSpecifier();
1226 if (baseAccess > accessSoFar) {
1227 constrainingBase = i;
1228 accessSoFar = baseAccess;
1231 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1232 case AR_inaccessible: break;
1233 case AR_accessible:
1234 accessSoFar = AS_public;
1235 entity.suppressInstanceContext();
1236 constrainingBase = nullptr;
1237 break;
1238 case AR_dependent:
1239 llvm_unreachable("cannot diagnose dependent access");
1242 // If this was private inheritance, but we don't have access to
1243 // the deriving class, we're done.
1244 if (accessSoFar == AS_private) {
1245 assert(baseAccess == AS_private);
1246 assert(constrainingBase == i);
1247 break;
1251 // If we don't have a constraining base, the access failure must be
1252 // due to the original declaration.
1253 if (constrainingBase == path.end())
1254 return diagnoseBadDirectAccess(S, EC, entity);
1256 // We're constrained by inheritance, but we want to say
1257 // "declared private here" if we're diagnosing a hierarchy
1258 // conversion and this is the final step.
1259 unsigned diagnostic;
1260 if (entity.isMemberAccess() ||
1261 constrainingBase + 1 != path.end()) {
1262 diagnostic = diag::note_access_constrained_by_path;
1263 } else {
1264 diagnostic = diag::note_access_natural;
1267 const CXXBaseSpecifier *base = constrainingBase->Base;
1269 S.Diag(base->getSourceRange().getBegin(), diagnostic)
1270 << base->getSourceRange()
1271 << (base->getAccessSpecifier() == AS_protected)
1272 << (base->getAccessSpecifierAsWritten() == AS_none);
1274 if (entity.isMemberAccess())
1275 S.Diag(entity.getTargetDecl()->getLocation(),
1276 diag::note_member_declared_at);
1279 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1280 const EffectiveContext &EC,
1281 AccessTarget &Entity) {
1282 const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1283 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1284 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1286 S.Diag(Loc, Entity.getDiag())
1287 << (Entity.getAccess() == AS_protected)
1288 << (D ? D->getDeclName() : DeclarationName())
1289 << S.Context.getTypeDeclType(NamingClass)
1290 << S.Context.getTypeDeclType(DeclaringClass);
1291 DiagnoseAccessPath(S, EC, Entity);
1294 /// MSVC has a bug where if during an using declaration name lookup,
1295 /// the declaration found is unaccessible (private) and that declaration
1296 /// was bring into scope via another using declaration whose target
1297 /// declaration is accessible (public) then no error is generated.
1298 /// Example:
1299 /// class A {
1300 /// public:
1301 /// int f();
1302 /// };
1303 /// class B : public A {
1304 /// private:
1305 /// using A::f;
1306 /// };
1307 /// class C : public B {
1308 /// private:
1309 /// using B::f;
1310 /// };
1312 /// Here, B::f is private so this should fail in Standard C++, but
1313 /// because B::f refers to A::f which is public MSVC accepts it.
1314 static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S,
1315 SourceLocation AccessLoc,
1316 AccessTarget &Entity) {
1317 if (UsingShadowDecl *Shadow =
1318 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1319 if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1320 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1321 if (Entity.getTargetDecl()->getAccess() == AS_private &&
1322 (OrigDecl->getAccess() == AS_public ||
1323 OrigDecl->getAccess() == AS_protected)) {
1324 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1325 << UD->getQualifiedNameAsString()
1326 << OrigDecl->getQualifiedNameAsString();
1327 return true;
1330 return false;
1333 /// Determines whether the accessed entity is accessible. Public members
1334 /// have been weeded out by this point.
1335 static AccessResult IsAccessible(Sema &S,
1336 const EffectiveContext &EC,
1337 AccessTarget &Entity) {
1338 // Determine the actual naming class.
1339 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1341 AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1342 assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1344 // Before we try to recalculate access paths, try to white-list
1345 // accesses which just trade in on the final step, i.e. accesses
1346 // which don't require [M4] or [B4]. These are by far the most
1347 // common forms of privileged access.
1348 if (UnprivilegedAccess != AS_none) {
1349 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1350 case AR_dependent:
1351 // This is actually an interesting policy decision. We don't
1352 // *have* to delay immediately here: we can do the full access
1353 // calculation in the hope that friendship on some intermediate
1354 // class will make the declaration accessible non-dependently.
1355 // But that's not cheap, and odds are very good (note: assertion
1356 // made without data) that the friend declaration will determine
1357 // access.
1358 return AR_dependent;
1360 case AR_accessible: return AR_accessible;
1361 case AR_inaccessible: break;
1365 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1367 // We lower member accesses to base accesses by pretending that the
1368 // member is a base class of its declaring class.
1369 AccessSpecifier FinalAccess;
1371 if (Entity.isMemberAccess()) {
1372 // Determine if the declaration is accessible from EC when named
1373 // in its declaring class.
1374 NamedDecl *Target = Entity.getTargetDecl();
1375 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1377 FinalAccess = Target->getAccess();
1378 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1379 case AR_accessible:
1380 // Target is accessible at EC when named in its declaring class.
1381 // We can now hill-climb and simply check whether the declaring
1382 // class is accessible as a base of the naming class. This is
1383 // equivalent to checking the access of a notional public
1384 // member with no instance context.
1385 FinalAccess = AS_public;
1386 Entity.suppressInstanceContext();
1387 break;
1388 case AR_inaccessible: break;
1389 case AR_dependent: return AR_dependent; // see above
1392 if (DeclaringClass == NamingClass)
1393 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1394 } else {
1395 FinalAccess = AS_public;
1398 assert(Entity.getDeclaringClass() != NamingClass);
1400 // Append the declaration's access if applicable.
1401 CXXBasePaths Paths;
1402 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1403 if (!Path)
1404 return AR_dependent;
1406 assert(Path->Access <= UnprivilegedAccess &&
1407 "access along best path worse than direct?");
1408 if (Path->Access == AS_public)
1409 return AR_accessible;
1410 return AR_inaccessible;
1413 static void DelayDependentAccess(Sema &S,
1414 const EffectiveContext &EC,
1415 SourceLocation Loc,
1416 const AccessTarget &Entity) {
1417 assert(EC.isDependent() && "delaying non-dependent access");
1418 DeclContext *DC = EC.getInnerContext();
1419 assert(DC->isDependentContext() && "delaying non-dependent access");
1420 DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
1421 Loc,
1422 Entity.isMemberAccess(),
1423 Entity.getAccess(),
1424 Entity.getTargetDecl(),
1425 Entity.getNamingClass(),
1426 Entity.getBaseObjectType(),
1427 Entity.getDiag());
1430 /// Checks access to an entity from the given effective context.
1431 static AccessResult CheckEffectiveAccess(Sema &S,
1432 const EffectiveContext &EC,
1433 SourceLocation Loc,
1434 AccessTarget &Entity) {
1435 assert(Entity.getAccess() != AS_public && "called for public access!");
1437 switch (IsAccessible(S, EC, Entity)) {
1438 case AR_dependent:
1439 DelayDependentAccess(S, EC, Loc, Entity);
1440 return AR_dependent;
1442 case AR_inaccessible:
1443 if (S.getLangOpts().MSVCCompat &&
1444 IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
1445 return AR_accessible;
1446 if (!Entity.isQuiet())
1447 DiagnoseBadAccess(S, Loc, EC, Entity);
1448 return AR_inaccessible;
1450 case AR_accessible:
1451 return AR_accessible;
1454 // silence unnecessary warning
1455 llvm_unreachable("invalid access result");
1458 static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1459 AccessTarget &Entity) {
1460 // If the access path is public, it's accessible everywhere.
1461 if (Entity.getAccess() == AS_public)
1462 return Sema::AR_accessible;
1464 // If we're currently parsing a declaration, we may need to delay
1465 // access control checking, because our effective context might be
1466 // different based on what the declaration comes out as.
1468 // For example, we might be parsing a declaration with a scope
1469 // specifier, like this:
1470 // A::private_type A::foo() { ... }
1472 // friend declaration should not be delayed because it may lead to incorrect
1473 // redeclaration chain, such as:
1474 // class D {
1475 // class E{
1476 // class F{};
1477 // friend void foo(D::E::F& q);
1478 // };
1479 // friend void foo(D::E::F& q);
1480 // };
1481 if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1482 // [class.friend]p9:
1483 // A member nominated by a friend declaration shall be accessible in the
1484 // class containing the friend declaration. The meaning of the friend
1485 // declaration is the same whether the friend declaration appears in the
1486 // private, protected, or public ([class.mem]) portion of the class
1487 // member-specification.
1488 Scope *TS = S.getCurScope();
1489 bool IsFriendDeclaration = false;
1490 while (TS && !IsFriendDeclaration) {
1491 IsFriendDeclaration = TS->isFriendScope();
1492 TS = TS->getParent();
1494 if (!IsFriendDeclaration) {
1495 S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
1496 return Sema::AR_delayed;
1500 EffectiveContext EC(S.CurContext);
1501 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1502 case AR_accessible: return Sema::AR_accessible;
1503 case AR_inaccessible: return Sema::AR_inaccessible;
1504 case AR_dependent: return Sema::AR_dependent;
1506 llvm_unreachable("invalid access result");
1509 void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
1510 // Access control for names used in the declarations of functions
1511 // and function templates should normally be evaluated in the context
1512 // of the declaration, just in case it's a friend of something.
1513 // However, this does not apply to local extern declarations.
1515 DeclContext *DC = D->getDeclContext();
1516 if (D->isLocalExternDecl()) {
1517 DC = D->getLexicalDeclContext();
1518 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1519 DC = FN;
1520 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1521 if (isa<DeclContext>(TD->getTemplatedDecl()))
1522 DC = cast<DeclContext>(TD->getTemplatedDecl());
1523 } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1524 DC = RD;
1527 EffectiveContext EC(DC);
1529 AccessTarget Target(DD.getAccessData());
1531 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1532 DD.Triggered = true;
1535 void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
1536 const MultiLevelTemplateArgumentList &TemplateArgs) {
1537 SourceLocation Loc = DD.getAccessLoc();
1538 AccessSpecifier Access = DD.getAccess();
1540 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1541 TemplateArgs);
1542 if (!NamingD) return;
1543 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1544 TemplateArgs);
1545 if (!TargetD) return;
1547 if (DD.isAccessToMember()) {
1548 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1549 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1550 QualType BaseObjectType = DD.getAccessBaseObjectType();
1551 if (!BaseObjectType.isNull()) {
1552 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1553 DeclarationName());
1554 if (BaseObjectType.isNull()) return;
1557 AccessTarget Entity(Context,
1558 AccessTarget::Member,
1559 NamingClass,
1560 DeclAccessPair::make(TargetDecl, Access),
1561 BaseObjectType);
1562 Entity.setDiag(DD.getDiagnostic());
1563 CheckAccess(*this, Loc, Entity);
1564 } else {
1565 AccessTarget Entity(Context,
1566 AccessTarget::Base,
1567 cast<CXXRecordDecl>(TargetD),
1568 cast<CXXRecordDecl>(NamingD),
1569 Access);
1570 Entity.setDiag(DD.getDiagnostic());
1571 CheckAccess(*this, Loc, Entity);
1575 Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
1576 DeclAccessPair Found) {
1577 if (!getLangOpts().AccessControl ||
1578 !E->getNamingClass() ||
1579 Found.getAccess() == AS_public)
1580 return AR_accessible;
1582 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1583 Found, QualType());
1584 Entity.setDiag(diag::err_access) << E->getSourceRange();
1586 return CheckAccess(*this, E->getNameLoc(), Entity);
1589 Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
1590 DeclAccessPair Found) {
1591 if (!getLangOpts().AccessControl ||
1592 Found.getAccess() == AS_public)
1593 return AR_accessible;
1595 QualType BaseType = E->getBaseType();
1596 if (E->isArrow())
1597 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1599 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1600 Found, BaseType);
1601 Entity.setDiag(diag::err_access) << E->getSourceRange();
1603 return CheckAccess(*this, E->getMemberLoc(), Entity);
1606 bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
1607 DeclAccessPair Found,
1608 QualType ObjectType,
1609 SourceLocation Loc,
1610 const PartialDiagnostic &Diag) {
1611 // Fast path.
1612 if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1613 return true;
1615 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1616 ObjectType);
1618 // Suppress diagnostics.
1619 Entity.setDiag(Diag);
1621 switch (CheckAccess(*this, Loc, Entity)) {
1622 case AR_accessible: return true;
1623 case AR_inaccessible: return false;
1624 case AR_dependent: llvm_unreachable("dependent for =delete computation");
1625 case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1627 llvm_unreachable("bad access result");
1630 Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
1631 CXXDestructorDecl *Dtor,
1632 const PartialDiagnostic &PDiag,
1633 QualType ObjectTy) {
1634 if (!getLangOpts().AccessControl)
1635 return AR_accessible;
1637 // There's never a path involved when checking implicit destructor access.
1638 AccessSpecifier Access = Dtor->getAccess();
1639 if (Access == AS_public)
1640 return AR_accessible;
1642 CXXRecordDecl *NamingClass = Dtor->getParent();
1643 if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1645 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1646 DeclAccessPair::make(Dtor, Access),
1647 ObjectTy);
1648 Entity.setDiag(PDiag); // TODO: avoid copy
1650 return CheckAccess(*this, Loc, Entity);
1653 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1654 CXXConstructorDecl *Constructor,
1655 DeclAccessPair Found,
1656 const InitializedEntity &Entity,
1657 bool IsCopyBindingRefToTemp) {
1658 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1659 return AR_accessible;
1661 PartialDiagnostic PD(PDiag());
1662 switch (Entity.getKind()) {
1663 default:
1664 PD = PDiag(IsCopyBindingRefToTemp
1665 ? diag::ext_rvalue_to_reference_access_ctor
1666 : diag::err_access_ctor);
1668 break;
1670 case InitializedEntity::EK_Base:
1671 PD = PDiag(diag::err_access_base_ctor);
1672 PD << Entity.isInheritedVirtualBase()
1673 << Entity.getBaseSpecifier()->getType()
1674 << llvm::to_underlying(getSpecialMember(Constructor));
1675 break;
1677 case InitializedEntity::EK_Member:
1678 case InitializedEntity::EK_ParenAggInitMember: {
1679 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1680 PD = PDiag(diag::err_access_field_ctor);
1681 PD << Field->getType()
1682 << llvm::to_underlying(getSpecialMember(Constructor));
1683 break;
1686 case InitializedEntity::EK_LambdaCapture: {
1687 StringRef VarName = Entity.getCapturedVarName();
1688 PD = PDiag(diag::err_access_lambda_capture);
1689 PD << VarName << Entity.getType()
1690 << llvm::to_underlying(getSpecialMember(Constructor));
1691 break;
1696 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1699 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1700 CXXConstructorDecl *Constructor,
1701 DeclAccessPair Found,
1702 const InitializedEntity &Entity,
1703 const PartialDiagnostic &PD) {
1704 if (!getLangOpts().AccessControl ||
1705 Found.getAccess() == AS_public)
1706 return AR_accessible;
1708 CXXRecordDecl *NamingClass = Constructor->getParent();
1710 // Initializing a base sub-object is an instance method call on an
1711 // object of the derived class. Otherwise, we have an instance method
1712 // call on an object of the constructed type.
1714 // FIXME: If we have a parent, we're initializing the base class subobject
1715 // in aggregate initialization. It's not clear whether the object class
1716 // should be the base class or the derived class in that case.
1717 CXXRecordDecl *ObjectClass;
1718 if ((Entity.getKind() == InitializedEntity::EK_Base ||
1719 Entity.getKind() == InitializedEntity::EK_Delegating) &&
1720 !Entity.getParent()) {
1721 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1722 } else if (auto *Shadow =
1723 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1724 // If we're using an inheriting constructor to construct an object,
1725 // the object class is the derived class, not the base class.
1726 ObjectClass = Shadow->getParent();
1727 } else {
1728 ObjectClass = NamingClass;
1731 AccessTarget AccessEntity(
1732 Context, AccessTarget::Member, NamingClass,
1733 DeclAccessPair::make(Constructor, Found.getAccess()),
1734 Context.getTypeDeclType(ObjectClass));
1735 AccessEntity.setDiag(PD);
1737 return CheckAccess(*this, UseLoc, AccessEntity);
1740 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
1741 SourceRange PlacementRange,
1742 CXXRecordDecl *NamingClass,
1743 DeclAccessPair Found,
1744 bool Diagnose) {
1745 if (!getLangOpts().AccessControl ||
1746 !NamingClass ||
1747 Found.getAccess() == AS_public)
1748 return AR_accessible;
1750 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1751 QualType());
1752 if (Diagnose)
1753 Entity.setDiag(diag::err_access)
1754 << PlacementRange;
1756 return CheckAccess(*this, OpLoc, Entity);
1759 Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
1760 CXXRecordDecl *NamingClass,
1761 DeclAccessPair Found) {
1762 if (!getLangOpts().AccessControl ||
1763 !NamingClass ||
1764 Found.getAccess() == AS_public)
1765 return AR_accessible;
1767 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1768 Found, QualType());
1770 return CheckAccess(*this, UseLoc, Entity);
1773 Sema::AccessResult
1774 Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
1775 CXXRecordDecl *DecomposedClass,
1776 DeclAccessPair Field) {
1777 if (!getLangOpts().AccessControl ||
1778 Field.getAccess() == AS_public)
1779 return AR_accessible;
1781 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1782 Context.getRecordType(DecomposedClass));
1783 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1785 return CheckAccess(*this, UseLoc, Entity);
1788 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1789 Expr *ObjectExpr,
1790 const SourceRange &Range,
1791 DeclAccessPair Found) {
1792 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1793 return AR_accessible;
1795 const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1796 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1798 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1799 ObjectExpr->getType());
1800 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1802 return CheckAccess(*this, OpLoc, Entity);
1805 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1806 Expr *ObjectExpr,
1807 Expr *ArgExpr,
1808 DeclAccessPair Found) {
1809 return CheckMemberOperatorAccess(
1810 OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1811 Found);
1814 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1815 Expr *ObjectExpr,
1816 ArrayRef<Expr *> ArgExprs,
1817 DeclAccessPair FoundDecl) {
1818 SourceRange R;
1819 if (!ArgExprs.empty()) {
1820 R = SourceRange(ArgExprs.front()->getBeginLoc(),
1821 ArgExprs.back()->getEndLoc());
1824 return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1827 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
1828 assert(isa<CXXMethodDecl>(target->getAsFunction()));
1830 // Friendship lookup is a redeclaration lookup, so there's never an
1831 // inheritance path modifying access.
1832 AccessSpecifier access = target->getAccess();
1834 if (!getLangOpts().AccessControl || access == AS_public)
1835 return AR_accessible;
1837 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1839 AccessTarget entity(Context, AccessTarget::Member,
1840 cast<CXXRecordDecl>(target->getDeclContext()),
1841 DeclAccessPair::make(target, access),
1842 /*no instance context*/ QualType());
1843 entity.setDiag(diag::err_access_friend_function)
1844 << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1845 : method->getNameInfo().getSourceRange());
1847 // We need to bypass delayed-diagnostics because we might be called
1848 // while the ParsingDeclarator is active.
1849 EffectiveContext EC(CurContext);
1850 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1851 case ::AR_accessible: return Sema::AR_accessible;
1852 case ::AR_inaccessible: return Sema::AR_inaccessible;
1853 case ::AR_dependent: return Sema::AR_dependent;
1855 llvm_unreachable("invalid access result");
1858 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
1859 DeclAccessPair Found) {
1860 if (!getLangOpts().AccessControl ||
1861 Found.getAccess() == AS_none ||
1862 Found.getAccess() == AS_public)
1863 return AR_accessible;
1865 OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1866 CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1868 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1869 /*no instance context*/ QualType());
1870 Entity.setDiag(diag::err_access)
1871 << Ovl->getSourceRange();
1873 return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1876 Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
1877 QualType Base,
1878 QualType Derived,
1879 const CXXBasePath &Path,
1880 unsigned DiagID,
1881 bool ForceCheck,
1882 bool ForceUnprivileged) {
1883 if (!ForceCheck && !getLangOpts().AccessControl)
1884 return AR_accessible;
1886 if (Path.Access == AS_public)
1887 return AR_accessible;
1889 CXXRecordDecl *BaseD, *DerivedD;
1890 BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1891 DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1893 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1894 Path.Access);
1895 if (DiagID)
1896 Entity.setDiag(DiagID) << Derived << Base;
1898 if (ForceUnprivileged) {
1899 switch (CheckEffectiveAccess(*this, EffectiveContext(),
1900 AccessLoc, Entity)) {
1901 case ::AR_accessible: return Sema::AR_accessible;
1902 case ::AR_inaccessible: return Sema::AR_inaccessible;
1903 case ::AR_dependent: return Sema::AR_dependent;
1905 llvm_unreachable("unexpected result from CheckEffectiveAccess");
1907 return CheckAccess(*this, AccessLoc, Entity);
1910 void Sema::CheckLookupAccess(const LookupResult &R) {
1911 assert(getLangOpts().AccessControl
1912 && "performing access check without access control");
1913 assert(R.getNamingClass() && "performing access check without naming class");
1915 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1916 if (I.getAccess() != AS_public) {
1917 AccessTarget Entity(Context, AccessedEntity::Member,
1918 R.getNamingClass(), I.getPair(),
1919 R.getBaseObjectType());
1920 Entity.setDiag(diag::err_access);
1921 CheckAccess(*this, R.getNameLoc(), Entity);
1926 bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
1927 QualType BaseType) {
1928 // Perform the C++ accessibility checks first.
1929 if (Target->isCXXClassMember() && NamingClass) {
1930 if (!getLangOpts().CPlusPlus)
1931 return false;
1932 // The unprivileged access is AS_none as we don't know how the member was
1933 // accessed, which is described by the access in DeclAccessPair.
1934 // `IsAccessible` will examine the actual access of Target (i.e.
1935 // Decl->getAccess()) when calculating the access.
1936 AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1937 DeclAccessPair::make(Target, AS_none), BaseType);
1938 EffectiveContext EC(CurContext);
1939 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1942 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1943 // @public and @package ivars are always accessible.
1944 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1945 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1946 return true;
1948 // If we are inside a class or category implementation, determine the
1949 // interface we're in.
1950 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1951 if (ObjCMethodDecl *MD = getCurMethodDecl())
1952 ClassOfMethodDecl = MD->getClassInterface();
1953 else if (FunctionDecl *FD = getCurFunctionDecl()) {
1954 if (ObjCImplDecl *Impl
1955 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1956 if (ObjCImplementationDecl *IMPD
1957 = dyn_cast<ObjCImplementationDecl>(Impl))
1958 ClassOfMethodDecl = IMPD->getClassInterface();
1959 else if (ObjCCategoryImplDecl* CatImplClass
1960 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1961 ClassOfMethodDecl = CatImplClass->getClassInterface();
1965 // If we're not in an interface, this ivar is inaccessible.
1966 if (!ClassOfMethodDecl)
1967 return false;
1969 // If we're inside the same interface that owns the ivar, we're fine.
1970 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1971 return true;
1973 // If the ivar is private, it's inaccessible.
1974 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1975 return false;
1977 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1980 return true;