1 //===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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
;
29 /// A copy of Sema's enum without AR_delayed.
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
);
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
);
58 MemberDecl
->setAccess(PrevMemberDecl
->getAccess());
62 static CXXRecordDecl
*FindDeclaringClass(NamedDecl
*D
) {
63 DeclContext
*DC
= D
->getDeclContext();
65 // This can only happen at top: enum decls only "publish" their
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
;
77 struct EffectiveContext
{
78 EffectiveContext() : Inner(nullptr), Dependent(false) {}
80 explicit EffectiveContext(DeclContext
*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();
91 // The copy deduction candidate doesn't have a corresponding
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
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.
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();
127 DC
= Function
->getDeclContext();
128 } else if (DC
->isFileContext()) {
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 {
149 typedef SmallVectorImpl
<CXXRecordDecl
*>::const_iterator record_iterator
;
152 SmallVector
<FunctionDecl
*, 4> Functions
;
153 SmallVector
<CXXRecordDecl
*, 4> Records
;
157 /// Like sema::AccessedEntity, but kindly lets us scribble all over
159 struct AccessTarget
: public AccessedEntity
{
160 AccessTarget(const AccessedEntity
&Entity
)
161 : AccessedEntity(Entity
) {
165 AccessTarget(ASTContext
&Context
,
167 CXXRecordDecl
*NamingClass
,
168 DeclAccessPair FoundDecl
,
169 QualType BaseObjectType
)
170 : AccessedEntity(Context
.getDiagAllocator(), Member
, NamingClass
,
171 FoundDecl
, BaseObjectType
) {
175 AccessTarget(ASTContext
&Context
,
177 CXXRecordDecl
*BaseClass
,
178 CXXRecordDecl
*DerivedClass
,
179 AccessSpecifier Access
)
180 : AccessedEntity(Context
.getDiagAllocator(), Base
, BaseClass
, DerivedClass
,
185 bool isInstanceMember() const {
186 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
189 bool hasInstanceContext() const {
190 return HasInstanceContext
;
193 class SavedInstanceContext
{
195 SavedInstanceContext(SavedInstanceContext
&&S
)
196 : Target(S
.Target
), Has(S
.Has
) {
200 // The move assignment operator is defined as deleted pending further
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() {
211 Target
->HasInstanceContext
= Has
;
215 friend struct AccessTarget
;
216 explicit SavedInstanceContext(AccessTarget
&Target
)
217 : Target(&Target
), Has(Target
.HasInstanceContext
) {}
218 AccessTarget
*Target
;
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()
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();
257 HasInstanceContext
= (isMemberAccess() &&
258 !getBaseObjectType().isNull() &&
259 getTargetDecl()->isCXXInstanceMember());
260 CalculatedInstanceContext
= false;
261 InstanceContext
= nullptr;
263 if (isMemberAccess())
264 DeclaringClass
= FindDeclaringClass(getTargetDecl());
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())
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;
294 /// Checks whether one class is derived from another, inclusively.
295 /// Properly indicates when it couldn't be determined due to
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
))
310 AccessResult OnFailure
= AR_inaccessible
;
311 SmallVector
<const CXXRecordDecl
*, 8> Queue
; // actually a stack
314 if (Derived
->isDependentContext() && !Derived
->hasDefinition() &&
315 !Derived
->isLambda())
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
>()) {
328 assert(T
->isDependentType() && "non-dependent base wasn't a record?");
329 OnFailure
= AR_dependent
;
333 RD
= RD
->getCanonicalDecl();
334 if (RD
== Target
) return AR_accessible
;
335 if (CheckDependent
&& MightInstantiateTo(RD
, Target
))
336 OnFailure
= AR_dependent
;
341 if (Queue
.empty()) break;
343 Derived
= Queue
.pop_back_val();
350 static bool MightInstantiateTo(Sema
&S
, DeclContext
*Context
,
351 DeclContext
*Friend
) {
352 if (Friend
== Context
)
355 assert(!Friend
->isDependentContext() &&
356 "can't handle friends with dependent contexts here");
358 if (!Context
->isDependentContext())
361 if (Friend
->isFileContext())
364 // TODO: this is very conservative
368 // Asks whether the type in 'context' can ever instantiate to the type
370 static bool MightInstantiateTo(Sema
&S
, CanQualType Context
, CanQualType Friend
) {
371 if (Friend
== Context
)
374 if (!Friend
->isDependentType() && !Context
->isDependentType())
377 // TODO: this is very conservative.
381 static bool MightInstantiateTo(Sema
&S
,
382 FunctionDecl
*Context
,
383 FunctionDecl
*Friend
) {
384 if (Context
->getDeclName() != Friend
->getDeclName())
387 if (!MightInstantiateTo(S
,
388 Context
->getDeclContext(),
389 Friend
->getDeclContext()))
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())
404 if (FriendTy
->getNumParams() != ContextTy
->getNumParams())
407 if (!MightInstantiateTo(S
, ContextTy
->getReturnType(),
408 FriendTy
->getReturnType()))
411 for (unsigned I
= 0, E
= FriendTy
->getNumParams(); I
!= E
; ++I
)
412 if (!MightInstantiateTo(S
, ContextTy
->getParamType(I
),
413 FriendTy
->getParamType(I
)))
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
))
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())
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
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.
479 CTD
= Record
->getDescribedClassTemplate();
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())
491 // If the template names don't match, it can't be a dependent
493 if (CTD
->getDeclName() != Friend
->getDeclName())
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()))
502 // Otherwise, it's a dependent match.
503 OnFailure
= AR_dependent
;
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
) {
519 return AR_accessible
;
521 if (EC
.isDependent() && MightInstantiateTo(S
, *I
, Friend
))
522 OnFailure
= AR_dependent
;
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();
542 FTD
= (*I
)->getDescribedFunctionTemplate();
546 FTD
= FTD
->getCanonicalDecl();
549 return AR_accessible
;
551 if (EC
.isDependent() && MightInstantiateTo(S
, FTD
, Friend
))
552 OnFailure
= AR_dependent
;
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
565 if (FriendD
->isInvalidDecl() || FriendD
->isUnsupportedFriend())
566 return AR_accessible
;
568 if (TypeSourceInfo
*T
= FriendD
->getFriendType())
569 return MatchesFriend(S
, EC
, T
->getType()->getCanonicalTypeUnqualified());
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
)) {
598 return AR_accessible
;
600 case AR_inaccessible
:
604 OnFailure
= AR_dependent
;
609 // That's it, give up.
615 /// A helper class for checking for a friend which will grant access
616 /// to a protected instance member.
617 struct ProtectedFriendContext
{
619 const EffectiveContext
&EC
;
620 const CXXRecordDecl
*NamingClass
;
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
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;
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
>()) {
681 assert(T
->isDependentType() && "non-dependent base wasn't a record?");
682 EverDependent
= true;
686 // Recurse. We don't need to clean up if this returns true.
687 CurPath
.push_back(RD
);
688 if (findFriendship(RD
->getCanonicalDecl(), BasePrivateDepth
))
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
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
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
;
768 if (Access
== AS_private
) {
769 if (ECRecord
== NamingClass
)
770 return AR_accessible
;
772 if (EC
.isDependent() && MightInstantiateTo(ECRecord
, NamingClass
))
773 OnFailure
= AR_dependent
;
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
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
832 if (NamingClass
== ECRecord
) return AR_accessible
;
834 // Otherwise, this context class tells us nothing; on to the next.
838 assert(Target
.isInstanceMember());
840 const CXXRecordDecl
*InstanceContext
= Target
.resolveInstanceContext(S
);
841 if (!InstanceContext
) {
842 OnFailure
= AR_dependent
;
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,
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
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
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
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
),
958 assert(isDerived
&& "derived class not actually derived from base");
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();
970 AccessTarget::SavedInstanceContext _
= Target
.saveInstanceContext();
972 // Walk through the path backwards.
973 AccessSpecifier PathAccess
= FinalAccess
;
974 CXXBasePath::iterator I
= PI
->end(), E
= PI
->begin();
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
983 if (PathAccess
== AS_private
) {
984 PathAccess
= AS_none
;
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;
996 PathAccess
= AS_public
;
998 // Future tests are not against members and so do not have
1000 Target
.suppressInstanceContext();
1003 AnyDependent
= true;
1008 // Note that we modify the path's Access field to the
1009 // friend-modified access.
1010 if (BestPath
== nullptr || PathAccess
< BestPath
->Access
) {
1012 BestPath
->Access
= PathAccess
;
1014 // Short-circuit if we found a public path.
1015 if (BestPath
->Access
== AS_public
)
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.
1033 /// Given that an entity has protected natural access, check whether
1034 /// access might be denied because of the protected member access
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())
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
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
);
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
:
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
);
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
))
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())
1135 PrevDecl
= TD
->getPreviousDecl();
1137 if (!PrevDecl
) break;
1141 CXXRecordDecl
*DeclaringClass
= FindDeclaringClass(D
);
1142 Decl
*ImmediateChild
;
1143 if (D
->getDeclContext() == DeclaringClass
)
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
)) {
1163 S
.Diag(D
->getLocation(), diag::note_access_natural
)
1164 << (unsigned) (D
->getAccess() == AS_protected
)
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
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.
1192 accessSoFar
= AS_public
;
1193 entity
.suppressInstanceContext();
1196 case AR_inaccessible
:
1197 if (accessSoFar
== AS_private
||
1198 declaringClass
== entity
.getEffectiveNamingClass())
1199 return diagnoseBadDirectAccess(S
, EC
, entity
);
1203 llvm_unreachable("cannot diagnose dependent access");
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
;
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;
1234 accessSoFar
= AS_public
;
1235 entity
.suppressInstanceContext();
1236 constrainingBase
= nullptr;
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
);
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
;
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.
1303 /// class B : public A {
1307 /// class C : public B {
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();
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
)) {
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
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
)) {
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();
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
);
1395 FinalAccess
= AS_public
;
1398 assert(Entity
.getDeclaringClass() != NamingClass
);
1400 // Append the declaration's access if applicable.
1402 CXXBasePath
*Path
= FindBestPath(S
, EC
, Entity
, FinalAccess
, Paths
);
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
,
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
,
1422 Entity
.isMemberAccess(),
1424 Entity
.getTargetDecl(),
1425 Entity
.getNamingClass(),
1426 Entity
.getBaseObjectType(),
1430 /// Checks access to an entity from the given effective context.
1431 static AccessResult
CheckEffectiveAccess(Sema
&S
,
1432 const EffectiveContext
&EC
,
1434 AccessTarget
&Entity
) {
1435 assert(Entity
.getAccess() != AS_public
&& "called for public access!");
1437 switch (IsAccessible(S
, EC
, Entity
)) {
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
;
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:
1477 // friend void foo(D::E::F& q);
1479 // friend void foo(D::E::F& q);
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
)) {
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
)) {
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(),
1542 if (!NamingD
) return;
1543 Decl
*TargetD
= FindInstantiatedDecl(Loc
, DD
.getAccessTarget(),
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
,
1554 if (BaseObjectType
.isNull()) return;
1557 AccessTarget
Entity(Context
,
1558 AccessTarget::Member
,
1560 DeclAccessPair::make(TargetDecl
, Access
),
1562 Entity
.setDiag(DD
.getDiagnostic());
1563 CheckAccess(*this, Loc
, Entity
);
1565 AccessTarget
Entity(Context
,
1567 cast
<CXXRecordDecl
>(TargetD
),
1568 cast
<CXXRecordDecl
>(NamingD
),
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(),
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();
1597 BaseType
= BaseType
->castAs
<PointerType
>()->getPointeeType();
1599 AccessTarget
Entity(Context
, AccessTarget::Member
, E
->getNamingClass(),
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
,
1610 const PartialDiagnostic
&Diag
) {
1612 if (Found
.getAccess() == AS_public
|| !getLangOpts().AccessControl
)
1615 AccessTarget
Entity(Context
, AccessTarget::Member
, NamingClass
, Found
,
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
),
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()) {
1664 PD
= PDiag(IsCopyBindingRefToTemp
1665 ? diag::ext_rvalue_to_reference_access_ctor
1666 : diag::err_access_ctor
);
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
));
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
));
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
));
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();
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
,
1745 if (!getLangOpts().AccessControl
||
1747 Found
.getAccess() == AS_public
)
1748 return AR_accessible
;
1750 AccessTarget
Entity(Context
, AccessTarget::Member
, NamingClass
, Found
,
1753 Entity
.setDiag(diag::err_access
)
1756 return CheckAccess(*this, OpLoc
, Entity
);
1759 Sema::AccessResult
Sema::CheckMemberAccess(SourceLocation UseLoc
,
1760 CXXRecordDecl
*NamingClass
,
1761 DeclAccessPair Found
) {
1762 if (!getLangOpts().AccessControl
||
1764 Found
.getAccess() == AS_public
)
1765 return AR_accessible
;
1767 AccessTarget
Entity(Context
, AccessTarget::Member
, NamingClass
,
1770 return CheckAccess(*this, UseLoc
, Entity
);
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
,
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
,
1808 DeclAccessPair Found
) {
1809 return CheckMemberOperatorAccess(
1810 OpLoc
, ObjectExpr
, ArgExpr
? ArgExpr
->getSourceRange() : SourceRange(),
1814 Sema::AccessResult
Sema::CheckMemberOperatorAccess(SourceLocation OpLoc
,
1816 ArrayRef
<Expr
*> ArgExprs
,
1817 DeclAccessPair FoundDecl
) {
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
,
1879 const CXXBasePath
&Path
,
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
,
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
)
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
)
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
)
1969 // If we're inside the same interface that owns the ivar, we're fine.
1970 if (declaresSameEntity(ClassOfMethodDecl
, Ivar
->getContainingInterface()))
1973 // If the ivar is private, it's inaccessible.
1974 if (Ivar
->getCanonicalAccessControl() == ObjCIvarDecl::Private
)
1977 return Ivar
->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl
);