clang 19.0.0git
SemaAccess.cpp
Go to the documentation of this file.
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.
10//
11//===----------------------------------------------------------------------===//
12
17#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
21#include "clang/AST/ExprCXX.h"
24#include "clang/Sema/Lookup.h"
25
26using namespace clang;
27using namespace sema;
28
29/// A copy of Sema's enum without AR_delayed.
34};
35
36/// SetMemberAccessSpecifier - Set the access specifier of a member.
37/// Returns true on error (when the previous member decl access specifier
38/// is different from the new member decl access specifier).
40 NamedDecl *PrevMemberDecl,
41 AccessSpecifier LexicalAS) {
42 if (!PrevMemberDecl) {
43 // Use the lexical access specifier.
44 MemberDecl->setAccess(LexicalAS);
45 return false;
46 }
47
48 // C++ [class.access.spec]p3: When a member is redeclared its access
49 // specifier must be same as its initial declaration.
50 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
51 Diag(MemberDecl->getLocation(),
52 diag::err_class_redeclared_with_different_access)
53 << MemberDecl << LexicalAS;
54 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
55 << PrevMemberDecl << PrevMemberDecl->getAccess();
56
57 MemberDecl->setAccess(LexicalAS);
58 return true;
59 }
60
61 MemberDecl->setAccess(PrevMemberDecl->getAccess());
62 return false;
63}
64
66 DeclContext *DC = D->getDeclContext();
67
68 // This can only happen at top: enum decls only "publish" their
69 // immediate members.
70 if (isa<EnumDecl>(DC))
71 DC = cast<EnumDecl>(DC)->getDeclContext();
72
73 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
74 while (DeclaringClass->isAnonymousStructOrUnion())
75 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
76 return DeclaringClass;
77}
78
79namespace {
80struct EffectiveContext {
81 EffectiveContext() : Inner(nullptr), Dependent(false) {}
82
83 explicit EffectiveContext(DeclContext *DC)
84 : Inner(DC),
85 Dependent(DC->isDependentContext()) {
86
87 // An implicit deduction guide is semantically in the context enclosing the
88 // class template, but for access purposes behaves like the constructor
89 // from which it was produced.
90 if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
91 if (DGD->isImplicit()) {
92 DC = DGD->getCorrespondingConstructor();
93 if (!DC) {
94 // The copy deduction candidate doesn't have a corresponding
95 // constructor.
96 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
97 }
98 }
99 }
100
101 // C++11 [class.access.nest]p1:
102 // A nested class is a member and as such has the same access
103 // rights as any other member.
104 // C++11 [class.access]p2:
105 // A member of a class can also access all the names to which
106 // the class has access. A local class of a member function
107 // may access the same names that the member function itself
108 // may access.
109 // This almost implies that the privileges of nesting are transitive.
110 // Technically it says nothing about the local classes of non-member
111 // functions (which can gain privileges through friendship), but we
112 // take that as an oversight.
113 while (true) {
114 // We want to add canonical declarations to the EC lists for
115 // simplicity of checking, but we need to walk up through the
116 // actual current DC chain. Otherwise, something like a local
117 // extern or friend which happens to be the canonical
118 // declaration will really mess us up.
119
120 if (isa<CXXRecordDecl>(DC)) {
121 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
122 Records.push_back(Record->getCanonicalDecl());
123 DC = Record->getDeclContext();
124 } else if (isa<FunctionDecl>(DC)) {
125 FunctionDecl *Function = cast<FunctionDecl>(DC);
126 Functions.push_back(Function->getCanonicalDecl());
127 if (Function->getFriendObjectKind())
128 DC = Function->getLexicalDeclContext();
129 else
130 DC = Function->getDeclContext();
131 } else if (DC->isFileContext()) {
132 break;
133 } else {
134 DC = DC->getParent();
135 }
136 }
137 }
138
139 bool isDependent() const { return Dependent; }
140
141 bool includesClass(const CXXRecordDecl *R) const {
142 R = R->getCanonicalDecl();
143 return llvm::is_contained(Records, R);
144 }
145
146 /// Retrieves the innermost "useful" context. Can be null if we're
147 /// doing access-control without privileges.
148 DeclContext *getInnerContext() const {
149 return Inner;
150 }
151
153
154 DeclContext *Inner;
157 bool Dependent;
158};
159
160/// Like sema::AccessedEntity, but kindly lets us scribble all over
161/// it.
162struct AccessTarget : public AccessedEntity {
163 AccessTarget(const AccessedEntity &Entity)
164 : AccessedEntity(Entity) {
165 initialize();
166 }
167
168 AccessTarget(ASTContext &Context,
169 MemberNonce _,
170 CXXRecordDecl *NamingClass,
171 DeclAccessPair FoundDecl,
172 QualType BaseObjectType)
173 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
174 FoundDecl, BaseObjectType) {
175 initialize();
176 }
177
178 AccessTarget(ASTContext &Context,
179 BaseNonce _,
180 CXXRecordDecl *BaseClass,
181 CXXRecordDecl *DerivedClass,
182 AccessSpecifier Access)
183 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
184 Access) {
185 initialize();
186 }
187
188 bool isInstanceMember() const {
189 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
190 }
191
192 bool hasInstanceContext() const {
193 return HasInstanceContext;
194 }
195
196 class SavedInstanceContext {
197 public:
198 SavedInstanceContext(SavedInstanceContext &&S)
199 : Target(S.Target), Has(S.Has) {
200 S.Target = nullptr;
201 }
202
203 // The move assignment operator is defined as deleted pending further
204 // motivation.
205 SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;
206
207 // The copy constrcutor and copy assignment operator is defined as deleted
208 // pending further motivation.
209 SavedInstanceContext(const SavedInstanceContext &) = delete;
210 SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;
211
212 ~SavedInstanceContext() {
213 if (Target)
214 Target->HasInstanceContext = Has;
215 }
216
217 private:
218 friend struct AccessTarget;
219 explicit SavedInstanceContext(AccessTarget &Target)
220 : Target(&Target), Has(Target.HasInstanceContext) {}
221 AccessTarget *Target;
222 bool Has;
223 };
224
225 SavedInstanceContext saveInstanceContext() {
226 return SavedInstanceContext(*this);
227 }
228
229 void suppressInstanceContext() {
230 HasInstanceContext = false;
231 }
232
233 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
234 assert(HasInstanceContext);
235 if (CalculatedInstanceContext)
236 return InstanceContext;
237
238 CalculatedInstanceContext = true;
239 DeclContext *IC = S.computeDeclContext(getBaseObjectType());
240 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
241 : nullptr);
242 return InstanceContext;
243 }
244
245 const CXXRecordDecl *getDeclaringClass() const {
246 return DeclaringClass;
247 }
248
249 /// The "effective" naming class is the canonical non-anonymous
250 /// class containing the actual naming class.
251 const CXXRecordDecl *getEffectiveNamingClass() const {
252 const CXXRecordDecl *namingClass = getNamingClass();
253 while (namingClass->isAnonymousStructOrUnion())
254 namingClass = cast<CXXRecordDecl>(namingClass->getParent());
255 return namingClass->getCanonicalDecl();
256 }
257
258private:
259 void initialize() {
260 HasInstanceContext = (isMemberAccess() &&
261 !getBaseObjectType().isNull() &&
262 getTargetDecl()->isCXXInstanceMember());
263 CalculatedInstanceContext = false;
264 InstanceContext = nullptr;
265
266 if (isMemberAccess())
267 DeclaringClass = FindDeclaringClass(getTargetDecl());
268 else
269 DeclaringClass = getBaseClass();
270 DeclaringClass = DeclaringClass->getCanonicalDecl();
271 }
272
273 bool HasInstanceContext : 1;
274 mutable bool CalculatedInstanceContext : 1;
275 mutable const CXXRecordDecl *InstanceContext;
276 const CXXRecordDecl *DeclaringClass;
277};
278
279}
280
281/// Checks whether one class might instantiate to the other.
282static bool MightInstantiateTo(const CXXRecordDecl *From,
283 const CXXRecordDecl *To) {
284 // Declaration names are always preserved by instantiation.
285 if (From->getDeclName() != To->getDeclName())
286 return false;
287
288 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
289 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
290 if (FromDC == ToDC) return true;
291 if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
292
293 // Be conservative.
294 return true;
295}
296
297/// Checks whether one class is derived from another, inclusively.
298/// Properly indicates when it couldn't be determined due to
299/// dependence.
300///
301/// This should probably be donated to AST or at least Sema.
303 const CXXRecordDecl *Target) {
304 assert(Derived->getCanonicalDecl() == Derived);
305 assert(Target->getCanonicalDecl() == Target);
306
307 if (Derived == Target) return AR_accessible;
308
309 bool CheckDependent = Derived->isDependentContext();
310 if (CheckDependent && MightInstantiateTo(Derived, Target))
311 return AR_dependent;
312
313 AccessResult OnFailure = AR_inaccessible;
314 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
315
316 while (true) {
317 if (Derived->isDependentContext() && !Derived->hasDefinition() &&
318 !Derived->isLambda())
319 return AR_dependent;
320
321 for (const auto &I : Derived->bases()) {
322 const CXXRecordDecl *RD;
323
324 QualType T = I.getType();
325 if (const RecordType *RT = T->getAs<RecordType>()) {
326 RD = cast<CXXRecordDecl>(RT->getDecl());
327 } else if (const InjectedClassNameType *IT
329 RD = IT->getDecl();
330 } else {
331 assert(T->isDependentType() && "non-dependent base wasn't a record?");
332 OnFailure = AR_dependent;
333 continue;
334 }
335
336 RD = RD->getCanonicalDecl();
337 if (RD == Target) return AR_accessible;
338 if (CheckDependent && MightInstantiateTo(RD, Target))
339 OnFailure = AR_dependent;
340
341 Queue.push_back(RD);
342 }
343
344 if (Queue.empty()) break;
345
346 Derived = Queue.pop_back_val();
347 }
348
349 return OnFailure;
350}
351
352
353static bool MightInstantiateTo(Sema &S, DeclContext *Context,
354 DeclContext *Friend) {
355 if (Friend == Context)
356 return true;
357
358 assert(!Friend->isDependentContext() &&
359 "can't handle friends with dependent contexts here");
360
361 if (!Context->isDependentContext())
362 return false;
363
364 if (Friend->isFileContext())
365 return false;
366
367 // TODO: this is very conservative
368 return true;
369}
370
371// Asks whether the type in 'context' can ever instantiate to the type
372// in 'friend'.
373static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
374 if (Friend == Context)
375 return true;
376
377 if (!Friend->isDependentType() && !Context->isDependentType())
378 return false;
379
380 // TODO: this is very conservative.
381 return true;
382}
383
385 FunctionDecl *Context,
386 FunctionDecl *Friend) {
387 if (Context->getDeclName() != Friend->getDeclName())
388 return false;
389
390 if (!MightInstantiateTo(S,
391 Context->getDeclContext(),
392 Friend->getDeclContext()))
393 return false;
394
396 = S.Context.getCanonicalType(Friend->getType())
399 = S.Context.getCanonicalType(Context->getType())
400 ->getAs<FunctionProtoType>();
401
402 // There isn't any way that I know of to add qualifiers
403 // during instantiation.
404 if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
405 return false;
406
407 if (FriendTy->getNumParams() != ContextTy->getNumParams())
408 return false;
409
410 if (!MightInstantiateTo(S, ContextTy->getReturnType(),
411 FriendTy->getReturnType()))
412 return false;
413
414 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
415 if (!MightInstantiateTo(S, ContextTy->getParamType(I),
416 FriendTy->getParamType(I)))
417 return false;
418
419 return true;
420}
421
423 FunctionTemplateDecl *Context,
424 FunctionTemplateDecl *Friend) {
425 return MightInstantiateTo(S,
426 Context->getTemplatedDecl(),
427 Friend->getTemplatedDecl());
428}
429
431 const EffectiveContext &EC,
432 const CXXRecordDecl *Friend) {
433 if (EC.includesClass(Friend))
434 return AR_accessible;
435
436 if (EC.isDependent()) {
437 for (const CXXRecordDecl *Context : EC.Records) {
438 if (MightInstantiateTo(Context, Friend))
439 return AR_dependent;
440 }
441 }
442
443 return AR_inaccessible;
444}
445
447 const EffectiveContext &EC,
448 CanQualType Friend) {
449 if (const RecordType *RT = Friend->getAs<RecordType>())
450 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
451
452 // TODO: we can do better than this
453 if (Friend->isDependentType())
454 return AR_dependent;
455
456 return AR_inaccessible;
457}
458
459/// Determines whether the given friend class template matches
460/// anything in the effective context.
462 const EffectiveContext &EC,
463 ClassTemplateDecl *Friend) {
464 AccessResult OnFailure = AR_inaccessible;
465
466 // Check whether the friend is the template of a class in the
467 // context chain.
469 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
470 CXXRecordDecl *Record = *I;
471
472 // Figure out whether the current class has a template:
474
475 // A specialization of the template...
476 if (isa<ClassTemplateSpecializationDecl>(Record)) {
477 CTD = cast<ClassTemplateSpecializationDecl>(Record)
478 ->getSpecializedTemplate();
479
480 // ... or the template pattern itself.
481 } else {
482 CTD = Record->getDescribedClassTemplate();
483 if (!CTD) continue;
484 }
485
486 // It's a match.
487 if (Friend == CTD->getCanonicalDecl())
488 return AR_accessible;
489
490 // If the context isn't dependent, it can't be a dependent match.
491 if (!EC.isDependent())
492 continue;
493
494 // If the template names don't match, it can't be a dependent
495 // match.
496 if (CTD->getDeclName() != Friend->getDeclName())
497 continue;
498
499 // If the class's context can't instantiate to the friend's
500 // context, it can't be a dependent match.
501 if (!MightInstantiateTo(S, CTD->getDeclContext(),
502 Friend->getDeclContext()))
503 continue;
504
505 // Otherwise, it's a dependent match.
506 OnFailure = AR_dependent;
507 }
508
509 return OnFailure;
510}
511
512/// Determines whether the given friend function matches anything in
513/// the effective context.
515 const EffectiveContext &EC,
516 FunctionDecl *Friend) {
517 AccessResult OnFailure = AR_inaccessible;
518
520 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
521 if (Friend == *I)
522 return AR_accessible;
523
524 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
525 OnFailure = AR_dependent;
526 }
527
528 return OnFailure;
529}
530
531/// Determines whether the given friend function template matches
532/// anything in the effective context.
534 const EffectiveContext &EC,
535 FunctionTemplateDecl *Friend) {
536 if (EC.Functions.empty()) return AR_inaccessible;
537
538 AccessResult OnFailure = AR_inaccessible;
539
541 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
542
543 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
544 if (!FTD)
545 FTD = (*I)->getDescribedFunctionTemplate();
546 if (!FTD)
547 continue;
548
549 FTD = FTD->getCanonicalDecl();
550
551 if (Friend == FTD)
552 return AR_accessible;
553
554 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
555 OnFailure = AR_dependent;
556 }
557
558 return OnFailure;
559}
560
561/// Determines whether the given friend declaration matches anything
562/// in the effective context.
564 const EffectiveContext &EC,
565 FriendDecl *FriendD) {
566 // Whitelist accesses if there's an invalid or unsupported friend
567 // declaration.
568 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
569 return AR_accessible;
570
571 if (TypeSourceInfo *T = FriendD->getFriendType())
572 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
573
574 NamedDecl *Friend
575 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
576
577 // FIXME: declarations with dependent or templated scope.
578
579 if (isa<ClassTemplateDecl>(Friend))
580 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
581
582 if (isa<FunctionTemplateDecl>(Friend))
583 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
584
585 if (isa<CXXRecordDecl>(Friend))
586 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
587
588 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
589 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
590}
591
593 const EffectiveContext &EC,
594 const CXXRecordDecl *Class) {
595 AccessResult OnFailure = AR_inaccessible;
596
597 // Okay, check friends.
598 for (auto *Friend : Class->friends()) {
599 switch (MatchesFriend(S, EC, Friend)) {
600 case AR_accessible:
601 return AR_accessible;
602
603 case AR_inaccessible:
604 continue;
605
606 case AR_dependent:
607 OnFailure = AR_dependent;
608 break;
609 }
610 }
611
612 // That's it, give up.
613 return OnFailure;
614}
615
616namespace {
617
618/// A helper class for checking for a friend which will grant access
619/// to a protected instance member.
620struct ProtectedFriendContext {
621 Sema &S;
622 const EffectiveContext &EC;
623 const CXXRecordDecl *NamingClass;
624 bool CheckDependent;
625 bool EverDependent;
626
627 /// The path down to the current base class.
629
630 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
631 const CXXRecordDecl *InstanceContext,
632 const CXXRecordDecl *NamingClass)
633 : S(S), EC(EC), NamingClass(NamingClass),
634 CheckDependent(InstanceContext->isDependentContext() ||
635 NamingClass->isDependentContext()),
636 EverDependent(false) {}
637
638 /// Check classes in the current path for friendship, starting at
639 /// the given index.
640 bool checkFriendshipAlongPath(unsigned I) {
641 assert(I < CurPath.size());
642 for (unsigned E = CurPath.size(); I != E; ++I) {
643 switch (GetFriendKind(S, EC, CurPath[I])) {
644 case AR_accessible: return true;
645 case AR_inaccessible: continue;
646 case AR_dependent: EverDependent = true; continue;
647 }
648 }
649 return false;
650 }
651
652 /// Perform a search starting at the given class.
653 ///
654 /// PrivateDepth is the index of the last (least derived) class
655 /// along the current path such that a notional public member of
656 /// the final class in the path would have access in that class.
657 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
658 // If we ever reach the naming class, check the current path for
659 // friendship. We can also stop recursing because we obviously
660 // won't find the naming class there again.
661 if (Cur == NamingClass)
662 return checkFriendshipAlongPath(PrivateDepth);
663
664 if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
665 EverDependent = true;
666
667 // Recurse into the base classes.
668 for (const auto &I : Cur->bases()) {
669 // If this is private inheritance, then a public member of the
670 // base will not have any access in classes derived from Cur.
671 unsigned BasePrivateDepth = PrivateDepth;
672 if (I.getAccessSpecifier() == AS_private)
673 BasePrivateDepth = CurPath.size() - 1;
674
675 const CXXRecordDecl *RD;
676
677 QualType T = I.getType();
678 if (const RecordType *RT = T->getAs<RecordType>()) {
679 RD = cast<CXXRecordDecl>(RT->getDecl());
680 } else if (const InjectedClassNameType *IT
682 RD = IT->getDecl();
683 } else {
684 assert(T->isDependentType() && "non-dependent base wasn't a record?");
685 EverDependent = true;
686 continue;
687 }
688
689 // Recurse. We don't need to clean up if this returns true.
690 CurPath.push_back(RD);
691 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
692 return true;
693 CurPath.pop_back();
694 }
695
696 return false;
697 }
698
699 bool findFriendship(const CXXRecordDecl *Cur) {
700 assert(CurPath.empty());
701 CurPath.push_back(Cur);
702 return findFriendship(Cur, 0);
703 }
704};
705}
706
707/// Search for a class P that EC is a friend of, under the constraint
708/// InstanceContext <= P
709/// if InstanceContext exists, or else
710/// NamingClass <= P
711/// and with the additional restriction that a protected member of
712/// NamingClass would have some natural access in P, which implicitly
713/// imposes the constraint that P <= NamingClass.
714///
715/// This isn't quite the condition laid out in the standard.
716/// Instead of saying that a notional protected member of NamingClass
717/// would have to have some natural access in P, it says the actual
718/// target has to have some natural access in P, which opens up the
719/// possibility that the target (which is not necessarily a member
720/// of NamingClass) might be more accessible along some path not
721/// passing through it. That's really a bad idea, though, because it
722/// introduces two problems:
723/// - Most importantly, it breaks encapsulation because you can
724/// access a forbidden base class's members by directly subclassing
725/// it elsewhere.
726/// - It also makes access substantially harder to compute because it
727/// breaks the hill-climbing algorithm: knowing that the target is
728/// accessible in some base class would no longer let you change
729/// the question solely to whether the base class is accessible,
730/// because the original target might have been more accessible
731/// because of crazy subclassing.
732/// So we don't implement that.
733static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
734 const CXXRecordDecl *InstanceContext,
735 const CXXRecordDecl *NamingClass) {
736 assert(InstanceContext == nullptr ||
737 InstanceContext->getCanonicalDecl() == InstanceContext);
738 assert(NamingClass->getCanonicalDecl() == NamingClass);
739
740 // If we don't have an instance context, our constraints give us
741 // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
742 // This is just the usual friendship check.
743 if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
744
745 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
746 if (PRC.findFriendship(InstanceContext)) return AR_accessible;
747 if (PRC.EverDependent) return AR_dependent;
748 return AR_inaccessible;
749}
750
752 const EffectiveContext &EC,
753 const CXXRecordDecl *NamingClass,
754 AccessSpecifier Access,
755 const AccessTarget &Target) {
756 assert(NamingClass->getCanonicalDecl() == NamingClass &&
757 "declaration should be canonicalized before being passed here");
758
759 if (Access == AS_public) return AR_accessible;
760 assert(Access == AS_private || Access == AS_protected);
761
762 AccessResult OnFailure = AR_inaccessible;
763
764 for (EffectiveContext::record_iterator
765 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
766 // All the declarations in EC have been canonicalized, so pointer
767 // equality from this point on will work fine.
768 const CXXRecordDecl *ECRecord = *I;
769
770 // [B2] and [M2]
771 if (Access == AS_private) {
772 if (ECRecord == NamingClass)
773 return AR_accessible;
774
775 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
776 OnFailure = AR_dependent;
777
778 // [B3] and [M3]
779 } else {
780 assert(Access == AS_protected);
781 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
782 case AR_accessible: break;
783 case AR_inaccessible: continue;
784 case AR_dependent: OnFailure = AR_dependent; continue;
785 }
786
787 // C++ [class.protected]p1:
788 // An additional access check beyond those described earlier in
789 // [class.access] is applied when a non-static data member or
790 // non-static member function is a protected member of its naming
791 // class. As described earlier, access to a protected member is
792 // granted because the reference occurs in a friend or member of
793 // some class C. If the access is to form a pointer to member,
794 // the nested-name-specifier shall name C or a class derived from
795 // C. All other accesses involve a (possibly implicit) object
796 // expression. In this case, the class of the object expression
797 // shall be C or a class derived from C.
798 //
799 // We interpret this as a restriction on [M3].
800
801 // In this part of the code, 'C' is just our context class ECRecord.
802
803 // These rules are different if we don't have an instance context.
804 if (!Target.hasInstanceContext()) {
805 // If it's not an instance member, these restrictions don't apply.
806 if (!Target.isInstanceMember()) return AR_accessible;
807
808 // If it's an instance member, use the pointer-to-member rule
809 // that the naming class has to be derived from the effective
810 // context.
811
812 // Emulate a MSVC bug where the creation of pointer-to-member
813 // to protected member of base class is allowed but only from
814 // static member functions.
815 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
816 if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
817 if (MD->isStatic()) return AR_accessible;
818
819 // Despite the standard's confident wording, there is a case
820 // where you can have an instance member that's neither in a
821 // pointer-to-member expression nor in a member access: when
822 // it names a field in an unevaluated context that can't be an
823 // implicit member. Pending clarification, we just apply the
824 // same naming-class restriction here.
825 // FIXME: we're probably not correctly adding the
826 // protected-member restriction when we retroactively convert
827 // an expression to being evaluated.
828
829 // We know that ECRecord derives from NamingClass. The
830 // restriction says to check whether NamingClass derives from
831 // ECRecord, but that's not really necessary: two distinct
832 // classes can't be recursively derived from each other. So
833 // along this path, we just need to check whether the classes
834 // are equal.
835 if (NamingClass == ECRecord) return AR_accessible;
836
837 // Otherwise, this context class tells us nothing; on to the next.
838 continue;
839 }
840
841 assert(Target.isInstanceMember());
842
843 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
844 if (!InstanceContext) {
845 OnFailure = AR_dependent;
846 continue;
847 }
848
849 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
850 case AR_accessible: return AR_accessible;
851 case AR_inaccessible: continue;
852 case AR_dependent: OnFailure = AR_dependent; continue;
853 }
854 }
855 }
856
857 // [M3] and [B3] say that, if the target is protected in N, we grant
858 // access if the access occurs in a friend or member of some class P
859 // that's a subclass of N and where the target has some natural
860 // access in P. The 'member' aspect is easy to handle because P
861 // would necessarily be one of the effective-context records, and we
862 // address that above. The 'friend' aspect is completely ridiculous
863 // to implement because there are no restrictions at all on P
864 // *unless* the [class.protected] restriction applies. If it does,
865 // however, we should ignore whether the naming class is a friend,
866 // and instead rely on whether any potential P is a friend.
867 if (Access == AS_protected && Target.isInstanceMember()) {
868 // Compute the instance context if possible.
869 const CXXRecordDecl *InstanceContext = nullptr;
870 if (Target.hasInstanceContext()) {
871 InstanceContext = Target.resolveInstanceContext(S);
872 if (!InstanceContext) return AR_dependent;
873 }
874
875 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
876 case AR_accessible: return AR_accessible;
877 case AR_inaccessible: return OnFailure;
878 case AR_dependent: return AR_dependent;
879 }
880 llvm_unreachable("impossible friendship kind");
881 }
882
883 switch (GetFriendKind(S, EC, NamingClass)) {
884 case AR_accessible: return AR_accessible;
885 case AR_inaccessible: return OnFailure;
886 case AR_dependent: return AR_dependent;
887 }
888
889 // Silence bogus warnings
890 llvm_unreachable("impossible friendship kind");
891}
892
893/// Finds the best path from the naming class to the declaring class,
894/// taking friend declarations into account.
895///
896/// C++0x [class.access.base]p5:
897/// A member m is accessible at the point R when named in class N if
898/// [M1] m as a member of N is public, or
899/// [M2] m as a member of N is private, and R occurs in a member or
900/// friend of class N, or
901/// [M3] m as a member of N is protected, and R occurs in a member or
902/// friend of class N, or in a member or friend of a class P
903/// derived from N, where m as a member of P is public, private,
904/// or protected, or
905/// [M4] there exists a base class B of N that is accessible at R, and
906/// m is accessible at R when named in class B.
907///
908/// C++0x [class.access.base]p4:
909/// A base class B of N is accessible at R, if
910/// [B1] an invented public member of B would be a public member of N, or
911/// [B2] R occurs in a member or friend of class N, and an invented public
912/// member of B would be a private or protected member of N, or
913/// [B3] R occurs in a member or friend of a class P derived from N, and an
914/// invented public member of B would be a private or protected member
915/// of P, or
916/// [B4] there exists a class S such that B is a base class of S accessible
917/// at R and S is a base class of N accessible at R.
918///
919/// Along a single inheritance path we can restate both of these
920/// iteratively:
921///
922/// First, we note that M1-4 are equivalent to B1-4 if the member is
923/// treated as a notional base of its declaring class with inheritance
924/// access equivalent to the member's access. Therefore we need only
925/// ask whether a class B is accessible from a class N in context R.
926///
927/// Let B_1 .. B_n be the inheritance path in question (i.e. where
928/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
929/// B_i). For i in 1..n, we will calculate ACAB(i), the access to the
930/// closest accessible base in the path:
931/// Access(a, b) = (* access on the base specifier from a to b *)
932/// Merge(a, forbidden) = forbidden
933/// Merge(a, private) = forbidden
934/// Merge(a, b) = min(a,b)
935/// Accessible(c, forbidden) = false
936/// Accessible(c, private) = (R is c) || IsFriend(c, R)
937/// Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
938/// Accessible(c, public) = true
939/// ACAB(n) = public
940/// ACAB(i) =
941/// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
942/// if Accessible(B_i, AccessToBase) then public else AccessToBase
943///
944/// B is an accessible base of N at R iff ACAB(1) = public.
945///
946/// \param FinalAccess the access of the "final step", or AS_public if
947/// there is no final step.
948/// \return null if friendship is dependent
950 const EffectiveContext &EC,
951 AccessTarget &Target,
952 AccessSpecifier FinalAccess,
953 CXXBasePaths &Paths) {
954 // Derive the paths to the desired base.
955 const CXXRecordDecl *Derived = Target.getNamingClass();
956 const CXXRecordDecl *Base = Target.getDeclaringClass();
957
958 // FIXME: fail correctly when there are dependent paths.
959 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
960 Paths);
961 assert(isDerived && "derived class not actually derived from base");
962 (void) isDerived;
963
964 CXXBasePath *BestPath = nullptr;
965
966 assert(FinalAccess != AS_none && "forbidden access after declaring class");
967
968 bool AnyDependent = false;
969
970 // Derive the friend-modified access along each path.
971 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
972 PI != PE; ++PI) {
973 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
974
975 // Walk through the path backwards.
976 AccessSpecifier PathAccess = FinalAccess;
977 CXXBasePath::iterator I = PI->end(), E = PI->begin();
978 while (I != E) {
979 --I;
980
981 assert(PathAccess != AS_none);
982
983 // If the declaration is a private member of a base class, there
984 // is no level of friendship in derived classes that can make it
985 // accessible.
986 if (PathAccess == AS_private) {
987 PathAccess = AS_none;
988 break;
989 }
990
991 const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
992
993 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
994 PathAccess = std::max(PathAccess, BaseAccess);
995
996 switch (HasAccess(S, EC, NC, PathAccess, Target)) {
997 case AR_inaccessible: break;
998 case AR_accessible:
999 PathAccess = AS_public;
1000
1001 // Future tests are not against members and so do not have
1002 // instance context.
1003 Target.suppressInstanceContext();
1004 break;
1005 case AR_dependent:
1006 AnyDependent = true;
1007 goto Next;
1008 }
1009 }
1010
1011 // Note that we modify the path's Access field to the
1012 // friend-modified access.
1013 if (BestPath == nullptr || PathAccess < BestPath->Access) {
1014 BestPath = &*PI;
1015 BestPath->Access = PathAccess;
1016
1017 // Short-circuit if we found a public path.
1018 if (BestPath->Access == AS_public)
1019 return BestPath;
1020 }
1021
1022 Next: ;
1023 }
1024
1025 assert((!BestPath || BestPath->Access != AS_public) &&
1026 "fell out of loop with public path");
1027
1028 // We didn't find a public path, but at least one path was subject
1029 // to dependent friendship, so delay the check.
1030 if (AnyDependent)
1031 return nullptr;
1032
1033 return BestPath;
1034}
1035
1036/// Given that an entity has protected natural access, check whether
1037/// access might be denied because of the protected member access
1038/// restriction.
1039///
1040/// \return true if a note was emitted
1041static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1042 AccessTarget &Target) {
1043 // Only applies to instance accesses.
1044 if (!Target.isInstanceMember())
1045 return false;
1046
1047 assert(Target.isMemberAccess());
1048
1049 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1050
1051 for (EffectiveContext::record_iterator
1052 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1053 const CXXRecordDecl *ECRecord = *I;
1054 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1055 case AR_accessible: break;
1056 case AR_inaccessible: continue;
1057 case AR_dependent: continue;
1058 }
1059
1060 // The effective context is a subclass of the declaring class.
1061 // Check whether the [class.protected] restriction is limiting
1062 // access.
1063
1064 // To get this exactly right, this might need to be checked more
1065 // holistically; it's not necessarily the case that gaining
1066 // access here would grant us access overall.
1067
1068 NamedDecl *D = Target.getTargetDecl();
1069
1070 // If we don't have an instance context, [class.protected] says the
1071 // naming class has to equal the context class.
1072 if (!Target.hasInstanceContext()) {
1073 // If it does, the restriction doesn't apply.
1074 if (NamingClass == ECRecord) continue;
1075
1076 // TODO: it would be great to have a fixit here, since this is
1077 // such an obvious error.
1078 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1079 << S.Context.getTypeDeclType(ECRecord);
1080 return true;
1081 }
1082
1083 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1084 assert(InstanceContext && "diagnosing dependent access");
1085
1086 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1087 case AR_accessible: continue;
1088 case AR_dependent: continue;
1089 case AR_inaccessible:
1090 break;
1091 }
1092
1093 // Okay, the restriction seems to be what's limiting us.
1094
1095 // Use a special diagnostic for constructors and destructors.
1096 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1097 (isa<FunctionTemplateDecl>(D) &&
1098 isa<CXXConstructorDecl>(
1099 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1100 return S.Diag(D->getLocation(),
1101 diag::note_access_protected_restricted_ctordtor)
1102 << isa<CXXDestructorDecl>(D->getAsFunction());
1103 }
1104
1105 // Otherwise, use the generic diagnostic.
1106 return S.Diag(D->getLocation(),
1107 diag::note_access_protected_restricted_object)
1108 << S.Context.getTypeDeclType(ECRecord);
1109 }
1110
1111 return false;
1112}
1113
1114/// We are unable to access a given declaration due to its direct
1115/// access control; diagnose that.
1117 const EffectiveContext &EC,
1118 AccessTarget &entity) {
1119 assert(entity.isMemberAccess());
1120 NamedDecl *D = entity.getTargetDecl();
1121
1122 if (D->getAccess() == AS_protected &&
1123 TryDiagnoseProtectedAccess(S, EC, entity))
1124 return;
1125
1126 // Find an original declaration.
1127 while (D->isOutOfLine()) {
1128 NamedDecl *PrevDecl = nullptr;
1129 if (VarDecl *VD = dyn_cast<VarDecl>(D))
1130 PrevDecl = VD->getPreviousDecl();
1131 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1132 PrevDecl = FD->getPreviousDecl();
1133 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1134 PrevDecl = TND->getPreviousDecl();
1135 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1136 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1137 break;
1138 PrevDecl = TD->getPreviousDecl();
1139 }
1140 if (!PrevDecl) break;
1141 D = PrevDecl;
1142 }
1143
1144 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1145 Decl *ImmediateChild;
1146 if (D->getDeclContext() == DeclaringClass)
1147 ImmediateChild = D;
1148 else {
1149 DeclContext *DC = D->getDeclContext();
1150 while (DC->getParent() != DeclaringClass)
1151 DC = DC->getParent();
1152 ImmediateChild = cast<Decl>(DC);
1153 }
1154
1155 // Check whether there's an AccessSpecDecl preceding this in the
1156 // chain of the DeclContext.
1157 bool isImplicit = true;
1158 for (const auto *I : DeclaringClass->decls()) {
1159 if (I == ImmediateChild) break;
1160 if (isa<AccessSpecDecl>(I)) {
1161 isImplicit = false;
1162 break;
1163 }
1164 }
1165
1166 S.Diag(D->getLocation(), diag::note_access_natural)
1167 << (unsigned) (D->getAccess() == AS_protected)
1168 << isImplicit;
1169}
1170
1171/// Diagnose the path which caused the given declaration or base class
1172/// to become inaccessible.
1174 const EffectiveContext &EC,
1175 AccessTarget &entity) {
1176 // Save the instance context to preserve invariants.
1177 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1178
1179 // This basically repeats the main algorithm but keeps some more
1180 // information.
1181
1182 // The natural access so far.
1183 AccessSpecifier accessSoFar = AS_public;
1184
1185 // Check whether we have special rights to the declaring class.
1186 if (entity.isMemberAccess()) {
1187 NamedDecl *D = entity.getTargetDecl();
1188 accessSoFar = D->getAccess();
1189 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1190
1191 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1192 // If the declaration is accessible when named in its declaring
1193 // class, then we must be constrained by the path.
1194 case AR_accessible:
1195 accessSoFar = AS_public;
1196 entity.suppressInstanceContext();
1197 break;
1198
1199 case AR_inaccessible:
1200 if (accessSoFar == AS_private ||
1201 declaringClass == entity.getEffectiveNamingClass())
1202 return diagnoseBadDirectAccess(S, EC, entity);
1203 break;
1204
1205 case AR_dependent:
1206 llvm_unreachable("cannot diagnose dependent access");
1207 }
1208 }
1209
1210 CXXBasePaths paths;
1211 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1212 assert(path.Access != AS_public);
1213
1214 CXXBasePath::iterator i = path.end(), e = path.begin();
1215 CXXBasePath::iterator constrainingBase = i;
1216 while (i != e) {
1217 --i;
1218
1219 assert(accessSoFar != AS_none && accessSoFar != AS_private);
1220
1221 // Is the entity accessible when named in the deriving class, as
1222 // modified by the base specifier?
1223 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1224 const CXXBaseSpecifier *base = i->Base;
1225
1226 // If the access to this base is worse than the access we have to
1227 // the declaration, remember it.
1228 AccessSpecifier baseAccess = base->getAccessSpecifier();
1229 if (baseAccess > accessSoFar) {
1230 constrainingBase = i;
1231 accessSoFar = baseAccess;
1232 }
1233
1234 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1235 case AR_inaccessible: break;
1236 case AR_accessible:
1237 accessSoFar = AS_public;
1238 entity.suppressInstanceContext();
1239 constrainingBase = nullptr;
1240 break;
1241 case AR_dependent:
1242 llvm_unreachable("cannot diagnose dependent access");
1243 }
1244
1245 // If this was private inheritance, but we don't have access to
1246 // the deriving class, we're done.
1247 if (accessSoFar == AS_private) {
1248 assert(baseAccess == AS_private);
1249 assert(constrainingBase == i);
1250 break;
1251 }
1252 }
1253
1254 // If we don't have a constraining base, the access failure must be
1255 // due to the original declaration.
1256 if (constrainingBase == path.end())
1257 return diagnoseBadDirectAccess(S, EC, entity);
1258
1259 // We're constrained by inheritance, but we want to say
1260 // "declared private here" if we're diagnosing a hierarchy
1261 // conversion and this is the final step.
1262 unsigned diagnostic;
1263 if (entity.isMemberAccess() ||
1264 constrainingBase + 1 != path.end()) {
1265 diagnostic = diag::note_access_constrained_by_path;
1266 } else {
1267 diagnostic = diag::note_access_natural;
1268 }
1269
1270 const CXXBaseSpecifier *base = constrainingBase->Base;
1271
1272 S.Diag(base->getSourceRange().getBegin(), diagnostic)
1273 << base->getSourceRange()
1274 << (base->getAccessSpecifier() == AS_protected)
1275 << (base->getAccessSpecifierAsWritten() == AS_none);
1276
1277 if (entity.isMemberAccess())
1278 S.Diag(entity.getTargetDecl()->getLocation(),
1279 diag::note_member_declared_at);
1280}
1281
1283 const EffectiveContext &EC,
1284 AccessTarget &Entity) {
1285 const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1286 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1287 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1288
1289 S.Diag(Loc, Entity.getDiag())
1290 << (Entity.getAccess() == AS_protected)
1291 << (D ? D->getDeclName() : DeclarationName())
1292 << S.Context.getTypeDeclType(NamingClass)
1293 << S.Context.getTypeDeclType(DeclaringClass);
1294 DiagnoseAccessPath(S, EC, Entity);
1295}
1296
1297/// MSVC has a bug where if during an using declaration name lookup,
1298/// the declaration found is unaccessible (private) and that declaration
1299/// was bring into scope via another using declaration whose target
1300/// declaration is accessible (public) then no error is generated.
1301/// Example:
1302/// class A {
1303/// public:
1304/// int f();
1305/// };
1306/// class B : public A {
1307/// private:
1308/// using A::f;
1309/// };
1310/// class C : public B {
1311/// private:
1312/// using B::f;
1313/// };
1314///
1315/// Here, B::f is private so this should fail in Standard C++, but
1316/// because B::f refers to A::f which is public MSVC accepts it.
1318 SourceLocation AccessLoc,
1319 AccessTarget &Entity) {
1320 if (UsingShadowDecl *Shadow =
1321 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1322 if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1323 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1324 if (Entity.getTargetDecl()->getAccess() == AS_private &&
1325 (OrigDecl->getAccess() == AS_public ||
1326 OrigDecl->getAccess() == AS_protected)) {
1327 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1328 << UD->getQualifiedNameAsString()
1329 << OrigDecl->getQualifiedNameAsString();
1330 return true;
1331 }
1332 }
1333 return false;
1334}
1335
1336/// Determines whether the accessed entity is accessible. Public members
1337/// have been weeded out by this point.
1339 const EffectiveContext &EC,
1340 AccessTarget &Entity) {
1341 // Determine the actual naming class.
1342 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1343
1344 AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1345 assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1346
1347 // Before we try to recalculate access paths, try to white-list
1348 // accesses which just trade in on the final step, i.e. accesses
1349 // which don't require [M4] or [B4]. These are by far the most
1350 // common forms of privileged access.
1351 if (UnprivilegedAccess != AS_none) {
1352 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1353 case AR_dependent:
1354 // This is actually an interesting policy decision. We don't
1355 // *have* to delay immediately here: we can do the full access
1356 // calculation in the hope that friendship on some intermediate
1357 // class will make the declaration accessible non-dependently.
1358 // But that's not cheap, and odds are very good (note: assertion
1359 // made without data) that the friend declaration will determine
1360 // access.
1361 return AR_dependent;
1362
1363 case AR_accessible: return AR_accessible;
1364 case AR_inaccessible: break;
1365 }
1366 }
1367
1368 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1369
1370 // We lower member accesses to base accesses by pretending that the
1371 // member is a base class of its declaring class.
1372 AccessSpecifier FinalAccess;
1373
1374 if (Entity.isMemberAccess()) {
1375 // Determine if the declaration is accessible from EC when named
1376 // in its declaring class.
1377 NamedDecl *Target = Entity.getTargetDecl();
1378 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1379
1380 FinalAccess = Target->getAccess();
1381 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1382 case AR_accessible:
1383 // Target is accessible at EC when named in its declaring class.
1384 // We can now hill-climb and simply check whether the declaring
1385 // class is accessible as a base of the naming class. This is
1386 // equivalent to checking the access of a notional public
1387 // member with no instance context.
1388 FinalAccess = AS_public;
1389 Entity.suppressInstanceContext();
1390 break;
1391 case AR_inaccessible: break;
1392 case AR_dependent: return AR_dependent; // see above
1393 }
1394
1395 if (DeclaringClass == NamingClass)
1396 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1397 } else {
1398 FinalAccess = AS_public;
1399 }
1400
1401 assert(Entity.getDeclaringClass() != NamingClass);
1402
1403 // Append the declaration's access if applicable.
1404 CXXBasePaths Paths;
1405 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1406 if (!Path)
1407 return AR_dependent;
1408
1409 assert(Path->Access <= UnprivilegedAccess &&
1410 "access along best path worse than direct?");
1411 if (Path->Access == AS_public)
1412 return AR_accessible;
1413 return AR_inaccessible;
1414}
1415
1417 const EffectiveContext &EC,
1418 SourceLocation Loc,
1419 const AccessTarget &Entity) {
1420 assert(EC.isDependent() && "delaying non-dependent access");
1421 DeclContext *DC = EC.getInnerContext();
1422 assert(DC->isDependentContext() && "delaying non-dependent access");
1424 Loc,
1425 Entity.isMemberAccess(),
1426 Entity.getAccess(),
1427 Entity.getTargetDecl(),
1428 Entity.getNamingClass(),
1429 Entity.getBaseObjectType(),
1430 Entity.getDiag());
1431}
1432
1433/// Checks access to an entity from the given effective context.
1435 const EffectiveContext &EC,
1436 SourceLocation Loc,
1437 AccessTarget &Entity) {
1438 assert(Entity.getAccess() != AS_public && "called for public access!");
1439
1440 switch (IsAccessible(S, EC, Entity)) {
1441 case AR_dependent:
1442 DelayDependentAccess(S, EC, Loc, Entity);
1443 return AR_dependent;
1444
1445 case AR_inaccessible:
1446 if (S.getLangOpts().MSVCCompat &&
1448 return AR_accessible;
1449 if (!Entity.isQuiet())
1450 DiagnoseBadAccess(S, Loc, EC, Entity);
1451 return AR_inaccessible;
1452
1453 case AR_accessible:
1454 return AR_accessible;
1455 }
1456
1457 // silence unnecessary warning
1458 llvm_unreachable("invalid access result");
1459}
1460
1462 AccessTarget &Entity) {
1463 // If the access path is public, it's accessible everywhere.
1464 if (Entity.getAccess() == AS_public)
1465 return Sema::AR_accessible;
1466
1467 // If we're currently parsing a declaration, we may need to delay
1468 // access control checking, because our effective context might be
1469 // different based on what the declaration comes out as.
1470 //
1471 // For example, we might be parsing a declaration with a scope
1472 // specifier, like this:
1473 // A::private_type A::foo() { ... }
1474 //
1475 // Or we might be parsing something that will turn out to be a friend:
1476 // void foo(A::private_type);
1477 // void B::foo(A::private_type);
1480 return Sema::AR_delayed;
1481 }
1482
1483 EffectiveContext EC(S.CurContext);
1484 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1487 case AR_dependent: return Sema::AR_dependent;
1488 }
1489 llvm_unreachable("invalid access result");
1490}
1491
1493 // Access control for names used in the declarations of functions
1494 // and function templates should normally be evaluated in the context
1495 // of the declaration, just in case it's a friend of something.
1496 // However, this does not apply to local extern declarations.
1497
1498 DeclContext *DC = D->getDeclContext();
1499 if (D->isLocalExternDecl()) {
1500 DC = D->getLexicalDeclContext();
1501 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1502 DC = FN;
1503 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1504 if (isa<DeclContext>(TD->getTemplatedDecl()))
1505 DC = cast<DeclContext>(TD->getTemplatedDecl());
1506 } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1507 DC = RD;
1508 }
1509
1510 EffectiveContext EC(DC);
1511
1512 AccessTarget Target(DD.getAccessData());
1513
1514 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1515 DD.Triggered = true;
1516}
1517
1519 const MultiLevelTemplateArgumentList &TemplateArgs) {
1520 SourceLocation Loc = DD.getAccessLoc();
1521 AccessSpecifier Access = DD.getAccess();
1522
1523 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1524 TemplateArgs);
1525 if (!NamingD) return;
1526 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1527 TemplateArgs);
1528 if (!TargetD) return;
1529
1530 if (DD.isAccessToMember()) {
1531 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1532 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1533 QualType BaseObjectType = DD.getAccessBaseObjectType();
1534 if (!BaseObjectType.isNull()) {
1535 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1536 DeclarationName());
1537 if (BaseObjectType.isNull()) return;
1538 }
1539
1540 AccessTarget Entity(Context,
1541 AccessTarget::Member,
1542 NamingClass,
1543 DeclAccessPair::make(TargetDecl, Access),
1544 BaseObjectType);
1545 Entity.setDiag(DD.getDiagnostic());
1546 CheckAccess(*this, Loc, Entity);
1547 } else {
1548 AccessTarget Entity(Context,
1549 AccessTarget::Base,
1550 cast<CXXRecordDecl>(TargetD),
1551 cast<CXXRecordDecl>(NamingD),
1552 Access);
1553 Entity.setDiag(DD.getDiagnostic());
1554 CheckAccess(*this, Loc, Entity);
1555 }
1556}
1557
1559 DeclAccessPair Found) {
1560 if (!getLangOpts().AccessControl ||
1561 !E->getNamingClass() ||
1562 Found.getAccess() == AS_public)
1563 return AR_accessible;
1564
1565 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1566 Found, QualType());
1567 Entity.setDiag(diag::err_access) << E->getSourceRange();
1568
1569 return CheckAccess(*this, E->getNameLoc(), Entity);
1570}
1571
1572/// Perform access-control checking on a previously-unresolved member
1573/// access which has now been resolved to a member.
1575 DeclAccessPair Found) {
1576 if (!getLangOpts().AccessControl ||
1577 Found.getAccess() == AS_public)
1578 return AR_accessible;
1579
1580 QualType BaseType = E->getBaseType();
1581 if (E->isArrow())
1582 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1583
1584 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1585 Found, BaseType);
1586 Entity.setDiag(diag::err_access) << E->getSourceRange();
1587
1588 return CheckAccess(*this, E->getMemberLoc(), Entity);
1589}
1590
1591/// Is the given member accessible for the purposes of deciding whether to
1592/// define a special member function as deleted?
1594 DeclAccessPair Found,
1595 QualType ObjectType,
1596 SourceLocation Loc,
1597 const PartialDiagnostic &Diag) {
1598 // Fast path.
1599 if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1600 return true;
1601
1602 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1603 ObjectType);
1604
1605 // Suppress diagnostics.
1606 Entity.setDiag(Diag);
1607
1608 switch (CheckAccess(*this, Loc, Entity)) {
1609 case AR_accessible: return true;
1610 case AR_inaccessible: return false;
1611 case AR_dependent: llvm_unreachable("dependent for =delete computation");
1612 case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1613 }
1614 llvm_unreachable("bad access result");
1615}
1616
1618 CXXDestructorDecl *Dtor,
1619 const PartialDiagnostic &PDiag,
1620 QualType ObjectTy) {
1621 if (!getLangOpts().AccessControl)
1622 return AR_accessible;
1623
1624 // There's never a path involved when checking implicit destructor access.
1625 AccessSpecifier Access = Dtor->getAccess();
1626 if (Access == AS_public)
1627 return AR_accessible;
1628
1629 CXXRecordDecl *NamingClass = Dtor->getParent();
1630 if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1631
1632 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1633 DeclAccessPair::make(Dtor, Access),
1634 ObjectTy);
1635 Entity.setDiag(PDiag); // TODO: avoid copy
1636
1637 return CheckAccess(*this, Loc, Entity);
1638}
1639
1640/// Checks access to a constructor.
1642 CXXConstructorDecl *Constructor,
1643 DeclAccessPair Found,
1644 const InitializedEntity &Entity,
1645 bool IsCopyBindingRefToTemp) {
1646 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1647 return AR_accessible;
1648
1650 switch (Entity.getKind()) {
1651 default:
1652 PD = PDiag(IsCopyBindingRefToTemp
1653 ? diag::ext_rvalue_to_reference_access_ctor
1654 : diag::err_access_ctor);
1655
1656 break;
1657
1659 PD = PDiag(diag::err_access_base_ctor);
1660 PD << Entity.isInheritedVirtualBase()
1661 << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1662 break;
1663
1666 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1667 PD = PDiag(diag::err_access_field_ctor);
1668 PD << Field->getType() << getSpecialMember(Constructor);
1669 break;
1670 }
1671
1673 StringRef VarName = Entity.getCapturedVarName();
1674 PD = PDiag(diag::err_access_lambda_capture);
1675 PD << VarName << Entity.getType() << getSpecialMember(Constructor);
1676 break;
1677 }
1678
1679 }
1680
1681 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1682}
1683
1684/// Checks access to a constructor.
1686 CXXConstructorDecl *Constructor,
1687 DeclAccessPair Found,
1688 const InitializedEntity &Entity,
1689 const PartialDiagnostic &PD) {
1690 if (!getLangOpts().AccessControl ||
1691 Found.getAccess() == AS_public)
1692 return AR_accessible;
1693
1694 CXXRecordDecl *NamingClass = Constructor->getParent();
1695
1696 // Initializing a base sub-object is an instance method call on an
1697 // object of the derived class. Otherwise, we have an instance method
1698 // call on an object of the constructed type.
1699 //
1700 // FIXME: If we have a parent, we're initializing the base class subobject
1701 // in aggregate initialization. It's not clear whether the object class
1702 // should be the base class or the derived class in that case.
1703 CXXRecordDecl *ObjectClass;
1704 if ((Entity.getKind() == InitializedEntity::EK_Base ||
1706 !Entity.getParent()) {
1707 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1708 } else if (auto *Shadow =
1709 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1710 // If we're using an inheriting constructor to construct an object,
1711 // the object class is the derived class, not the base class.
1712 ObjectClass = Shadow->getParent();
1713 } else {
1714 ObjectClass = NamingClass;
1715 }
1716
1717 AccessTarget AccessEntity(
1718 Context, AccessTarget::Member, NamingClass,
1719 DeclAccessPair::make(Constructor, Found.getAccess()),
1720 Context.getTypeDeclType(ObjectClass));
1721 AccessEntity.setDiag(PD);
1722
1723 return CheckAccess(*this, UseLoc, AccessEntity);
1724}
1725
1726/// Checks access to an overloaded operator new or delete.
1728 SourceRange PlacementRange,
1729 CXXRecordDecl *NamingClass,
1730 DeclAccessPair Found,
1731 bool Diagnose) {
1732 if (!getLangOpts().AccessControl ||
1733 !NamingClass ||
1734 Found.getAccess() == AS_public)
1735 return AR_accessible;
1736
1737 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1738 QualType());
1739 if (Diagnose)
1740 Entity.setDiag(diag::err_access)
1741 << PlacementRange;
1742
1743 return CheckAccess(*this, OpLoc, Entity);
1744}
1745
1746/// Checks access to a member.
1748 CXXRecordDecl *NamingClass,
1749 DeclAccessPair Found) {
1750 if (!getLangOpts().AccessControl ||
1751 !NamingClass ||
1752 Found.getAccess() == AS_public)
1753 return AR_accessible;
1754
1755 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1756 Found, QualType());
1757
1758 return CheckAccess(*this, UseLoc, Entity);
1759}
1760
1761/// Checks implicit access to a member in a structured binding.
1764 CXXRecordDecl *DecomposedClass,
1765 DeclAccessPair Field) {
1766 if (!getLangOpts().AccessControl ||
1767 Field.getAccess() == AS_public)
1768 return AR_accessible;
1769
1770 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1771 Context.getRecordType(DecomposedClass));
1772 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1773
1774 return CheckAccess(*this, UseLoc, Entity);
1775}
1776
1778 Expr *ObjectExpr,
1779 const SourceRange &Range,
1780 DeclAccessPair Found) {
1781 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1782 return AR_accessible;
1783
1784 const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1785 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1786
1787 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1788 ObjectExpr->getType());
1789 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1790
1791 return CheckAccess(*this, OpLoc, Entity);
1792}
1793
1794/// Checks access to an overloaded member operator, including
1795/// conversion operators.
1797 Expr *ObjectExpr,
1798 Expr *ArgExpr,
1799 DeclAccessPair Found) {
1801 OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1802 Found);
1803}
1804
1806 Expr *ObjectExpr,
1807 ArrayRef<Expr *> ArgExprs,
1808 DeclAccessPair FoundDecl) {
1809 SourceRange R;
1810 if (!ArgExprs.empty()) {
1811 R = SourceRange(ArgExprs.front()->getBeginLoc(),
1812 ArgExprs.back()->getEndLoc());
1813 }
1814
1815 return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1816}
1817
1818/// Checks access to the target of a friend declaration.
1820 assert(isa<CXXMethodDecl>(target->getAsFunction()));
1821
1822 // Friendship lookup is a redeclaration lookup, so there's never an
1823 // inheritance path modifying access.
1824 AccessSpecifier access = target->getAccess();
1825
1826 if (!getLangOpts().AccessControl || access == AS_public)
1827 return AR_accessible;
1828
1829 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1830
1831 AccessTarget entity(Context, AccessTarget::Member,
1832 cast<CXXRecordDecl>(target->getDeclContext()),
1833 DeclAccessPair::make(target, access),
1834 /*no instance context*/ QualType());
1835 entity.setDiag(diag::err_access_friend_function)
1836 << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1837 : method->getNameInfo().getSourceRange());
1838
1839 // We need to bypass delayed-diagnostics because we might be called
1840 // while the ParsingDeclarator is active.
1841 EffectiveContext EC(CurContext);
1842 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1843 case ::AR_accessible: return Sema::AR_accessible;
1844 case ::AR_inaccessible: return Sema::AR_inaccessible;
1845 case ::AR_dependent: return Sema::AR_dependent;
1846 }
1847 llvm_unreachable("invalid access result");
1848}
1849
1851 DeclAccessPair Found) {
1852 if (!getLangOpts().AccessControl ||
1853 Found.getAccess() == AS_none ||
1854 Found.getAccess() == AS_public)
1855 return AR_accessible;
1856
1858 CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1859
1860 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1861 /*no instance context*/ QualType());
1862 Entity.setDiag(diag::err_access)
1863 << Ovl->getSourceRange();
1864
1865 return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1866}
1867
1868/// Checks access for a hierarchy conversion.
1869///
1870/// \param ForceCheck true if this check should be performed even if access
1871/// control is disabled; some things rely on this for semantics
1872/// \param ForceUnprivileged true if this check should proceed as if the
1873/// context had no special privileges
1875 QualType Base,
1876 QualType Derived,
1877 const CXXBasePath &Path,
1878 unsigned DiagID,
1879 bool ForceCheck,
1880 bool ForceUnprivileged) {
1881 if (!ForceCheck && !getLangOpts().AccessControl)
1882 return AR_accessible;
1883
1884 if (Path.Access == AS_public)
1885 return AR_accessible;
1886
1887 CXXRecordDecl *BaseD, *DerivedD;
1888 BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1889 DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1890
1891 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1892 Path.Access);
1893 if (DiagID)
1894 Entity.setDiag(DiagID) << Derived << Base;
1895
1896 if (ForceUnprivileged) {
1897 switch (CheckEffectiveAccess(*this, EffectiveContext(),
1898 AccessLoc, Entity)) {
1899 case ::AR_accessible: return Sema::AR_accessible;
1900 case ::AR_inaccessible: return Sema::AR_inaccessible;
1901 case ::AR_dependent: return Sema::AR_dependent;
1902 }
1903 llvm_unreachable("unexpected result from CheckEffectiveAccess");
1904 }
1905 return CheckAccess(*this, AccessLoc, Entity);
1906}
1907
1908/// Checks access to all the declarations in the given result set.
1910 assert(getLangOpts().AccessControl
1911 && "performing access check without access control");
1912 assert(R.getNamingClass() && "performing access check without naming class");
1913
1914 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1915 if (I.getAccess() != AS_public) {
1916 AccessTarget Entity(Context, AccessedEntity::Member,
1917 R.getNamingClass(), I.getPair(),
1918 R.getBaseObjectType());
1919 Entity.setDiag(diag::err_access);
1920 CheckAccess(*this, R.getNameLoc(), Entity);
1921 }
1922 }
1923}
1924
1925/// Checks access to Target from the given class. The check will take access
1926/// specifiers into account, but no member access expressions and such.
1927///
1928/// \param Target the declaration to check if it can be accessed
1929/// \param NamingClass the class in which the lookup was started.
1930/// \param BaseType type of the left side of member access expression.
1931/// \p BaseType and \p NamingClass are used for C++ access control.
1932/// Depending on the lookup case, they should be set to the following:
1933/// - lhs.target (member access without a qualifier):
1934/// \p BaseType and \p NamingClass are both the type of 'lhs'.
1935/// - lhs.X::target (member access with a qualifier):
1936/// BaseType is the type of 'lhs', NamingClass is 'X'
1937/// - X::target (qualified lookup without member access):
1938/// BaseType is null, NamingClass is 'X'.
1939/// - target (unqualified lookup).
1940/// BaseType is null, NamingClass is the parent class of 'target'.
1941/// \return true if the Target is accessible from the Class, false otherwise.
1943 QualType BaseType) {
1944 // Perform the C++ accessibility checks first.
1945 if (Target->isCXXClassMember() && NamingClass) {
1946 if (!getLangOpts().CPlusPlus)
1947 return false;
1948 // The unprivileged access is AS_none as we don't know how the member was
1949 // accessed, which is described by the access in DeclAccessPair.
1950 // `IsAccessible` will examine the actual access of Target (i.e.
1951 // Decl->getAccess()) when calculating the access.
1952 AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1953 DeclAccessPair::make(Target, AS_none), BaseType);
1954 EffectiveContext EC(CurContext);
1955 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1956 }
1957
1958 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1959 // @public and @package ivars are always accessible.
1960 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1961 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1962 return true;
1963
1964 // If we are inside a class or category implementation, determine the
1965 // interface we're in.
1966 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1967 if (ObjCMethodDecl *MD = getCurMethodDecl())
1968 ClassOfMethodDecl = MD->getClassInterface();
1969 else if (FunctionDecl *FD = getCurFunctionDecl()) {
1970 if (ObjCImplDecl *Impl
1971 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1972 if (ObjCImplementationDecl *IMPD
1973 = dyn_cast<ObjCImplementationDecl>(Impl))
1974 ClassOfMethodDecl = IMPD->getClassInterface();
1975 else if (ObjCCategoryImplDecl* CatImplClass
1976 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1977 ClassOfMethodDecl = CatImplClass->getClassInterface();
1978 }
1979 }
1980
1981 // If we're not in an interface, this ivar is inaccessible.
1982 if (!ClassOfMethodDecl)
1983 return false;
1984
1985 // If we're inside the same interface that owns the ivar, we're fine.
1986 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1987 return true;
1988
1989 // If the ivar is private, it's inaccessible.
1990 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1991 return false;
1992
1993 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1994 }
1995
1996 return true;
1997}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
AccessResult
A copy of Sema's enum without AR_delayed.
Definition: SemaAccess.cpp:30
@ AR_accessible
Definition: SemaAccess.cpp:31
@ AR_dependent
Definition: SemaAccess.cpp:33
@ AR_inaccessible
Definition: SemaAccess.cpp:32
static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, AccessTarget &Target)
Given that an entity has protected natural access, check whether access might be denied because of th...
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
Checks whether one class is derived from another, inclusively.
Definition: SemaAccess.cpp:302
static void diagnoseBadDirectAccess(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
We are unable to access a given declaration due to its direct access control; diagnose that.
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)
Definition: SemaAccess.cpp:592
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
Definition: SemaAccess.cpp:430
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass)
Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...
Definition: SemaAccess.cpp:733
static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)
MSVC has a bug where if during an using declaration name lookup, the declaration found is unaccessibl...
static CXXBasePath * FindBestPath(Sema &S, const EffectiveContext &EC, AccessTarget &Target, AccessSpecifier FinalAccess, CXXBasePaths &Paths)
Finds the best path from the naming class to the declaring class, taking friend declarations into acc...
Definition: SemaAccess.cpp:949
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)
Determines whether the accessed entity is accessible.
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target)
Definition: SemaAccess.cpp:751
static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
Definition: SemaAccess.cpp:282
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
Diagnose the path which caused the given declaration or base class to become inaccessible.
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
Definition: SemaAccess.cpp:65
static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity)
Checks access to an entity from the given effective context.
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
Defines various enumerations that describe declaration and type specifiers.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
QualType getRecordType(const RecordDecl *Decl) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2549
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1575
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
std::list< CXXBasePath >::iterator paths_iterator
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
Definition: DeclCXX.h:242
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:249
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Definition: DeclCXX.h:193
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Definition: DeclCXX.h:230
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2528
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2792
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2053
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2179
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_range bases()
Definition: DeclCXX.h:618
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1021
bool hasDefinition() const
Definition: DeclCXX.h:571
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:523
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
Declaration of a class template.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
NamedDecl * getDecl() const
AccessSpecifier getAccess() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
bool isFileContext() const
Definition: DeclBase.h:2136
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1260
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1350
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2321
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1051
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
Definition: Decl.cpp:100
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:227
bool isInvalidDecl() const
Definition: DeclBase.h:593
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
Definition: DeclBase.h:1159
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:507
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getDeclContext()
Definition: DeclBase.h:453
AccessSpecifier getAccess() const
Definition: DeclBase.h:512
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:908
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
The name of a declaration.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition: Decl.h:828
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:836
A dependently-generated diagnostic.
NamedDecl * getAccessNamingClass() const
QualType getAccessBaseObjectType() const
NamedDecl * getAccessTarget() const
SourceLocation getAccessLoc() const
const PartialDiagnostic & getDiagnostic() const
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
AccessSpecifier getAccess() const
This represents one expression.
Definition: Expr.h:110
QualType getType() const
Definition: Expr.h:142
Represents a member of a struct/union/class.
Definition: Decl.h:3025
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:54
bool isUnsupportedFriend() const
Determines if this friend kind is unsupported.
Definition: DeclFriend.h:173
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:137
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:122
Represents a function declaration or definition.
Definition: Decl.h:1959
DeclarationNameInfo getNameInfo() const
Definition: Decl.h:2157
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4198
Declaration of a template function.
Definition: DeclTemplate.h:958
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Describes an entity that is being initialized.
EntityKind getKind() const
Determine the kind of initialization.
QualType getType() const
Retrieve type being initialized.
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
Definition: SemaInit.cpp:3490
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
@ EK_Member
The entity being initialized is a non-static data member subobject.
@ EK_Base
The entity being initialized is a base member subobject.
@ EK_ParenAggInitMember
The entity being initialized is a non-static data member subobject of an object initialized via paren...
@ EK_Delegating
The initialization is being done by a delegating constructor.
@ EK_LambdaCapture
The entity being initialized is the field that captures a variable in a lambda.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:5763
Represents the results of name lookup.
Definition: Lookup.h:46
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:659
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
Definition: Lookup.h:449
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected].
Definition: Lookup.h:461
iterator end() const
Definition: Lookup.h:356
iterator begin() const
Definition: Lookup.h:355
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1683
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2595
Represents an ObjC class declaration.
Definition: DeclObjC.h:1150
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition: DeclObjC.h:1805
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1947
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2966
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
Definition: ExprCXX.h:3026
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3078
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
Definition: ExprCXX.h:4078
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2897
A (possibly-)qualified type.
Definition: Type.h:737
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:804
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition: Decl.h:4185
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5091
RecordDecl * getDecl() const
Definition: Type.h:5101
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
Definition: Sema.h:1053
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:425
CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD)
Definition: Sema.h:3610
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
Definition: SemaAccess.cpp:39
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1924
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
AccessResult
Definition: Sema.h:8171
@ AR_dependent
Definition: Sema.h:8174
@ AR_accessible
Definition: Sema.h:8172
@ AR_inaccessible
Definition: Sema.h:8173
@ AR_delayed
Definition: Sema.h:8175
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)
Is the given member accessible for the purposes of deciding whether to define a special member functi...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1502
ASTContext & Context
Definition: Sema.h:476
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition: Sema.cpp:1507
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
const LangOptions & getLangOpts() const
Definition: Sema.h:1794
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)
Checks access to Target from the given class.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:489
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void CheckLookupAccess(const LookupResult &R)
Checks access to all the declarations in the given result set.
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3549
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
A container of type source information.
Definition: Type.h:6872
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7719
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2419
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7652
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3399
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3163
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition: ExprCXX.h:3239
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3905
QualType getBaseType() const
Definition: ExprCXX.h:3987
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition: ExprCXX.h:3997
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
Definition: ExprCXX.cpp:1617
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
Definition: ExprCXX.h:4017
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
Represents a C++ using-declaration.
Definition: DeclCXX.h:3505
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3313
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
A declaration being accessed, together with information about how it was accessed.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
The JSON file list parser is used to communicate input to InstallAPI.
@ CPlusPlus
Definition: LangStandard.h:54
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1275
@ Class
The "class" keyword introduces the elaborated-type-specifier.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:120
@ AS_public
Definition: Specifiers.h:121
@ AS_protected
Definition: Specifiers.h:122
@ AS_none
Definition: Specifiers.h:124
@ AS_private
Definition: Specifiers.h:123
#define false
Definition: stdbool.h:22
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.