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