xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaAccess.cpp (revision e6bfd18d21b225af6a0ed67ceeaf1293b7b9eba5)
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   }
1497 
1498   EffectiveContext EC(DC);
1499 
1500   AccessTarget Target(DD.getAccessData());
1501 
1502   if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1503     DD.Triggered = true;
1504 }
1505 
1506 void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
1507                         const MultiLevelTemplateArgumentList &TemplateArgs) {
1508   SourceLocation Loc = DD.getAccessLoc();
1509   AccessSpecifier Access = DD.getAccess();
1510 
1511   Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1512                                        TemplateArgs);
1513   if (!NamingD) return;
1514   Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1515                                        TemplateArgs);
1516   if (!TargetD) return;
1517 
1518   if (DD.isAccessToMember()) {
1519     CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1520     NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1521     QualType BaseObjectType = DD.getAccessBaseObjectType();
1522     if (!BaseObjectType.isNull()) {
1523       BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1524                                  DeclarationName());
1525       if (BaseObjectType.isNull()) return;
1526     }
1527 
1528     AccessTarget Entity(Context,
1529                         AccessTarget::Member,
1530                         NamingClass,
1531                         DeclAccessPair::make(TargetDecl, Access),
1532                         BaseObjectType);
1533     Entity.setDiag(DD.getDiagnostic());
1534     CheckAccess(*this, Loc, Entity);
1535   } else {
1536     AccessTarget Entity(Context,
1537                         AccessTarget::Base,
1538                         cast<CXXRecordDecl>(TargetD),
1539                         cast<CXXRecordDecl>(NamingD),
1540                         Access);
1541     Entity.setDiag(DD.getDiagnostic());
1542     CheckAccess(*this, Loc, Entity);
1543   }
1544 }
1545 
1546 Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
1547                                                      DeclAccessPair Found) {
1548   if (!getLangOpts().AccessControl ||
1549       !E->getNamingClass() ||
1550       Found.getAccess() == AS_public)
1551     return AR_accessible;
1552 
1553   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1554                       Found, QualType());
1555   Entity.setDiag(diag::err_access) << E->getSourceRange();
1556 
1557   return CheckAccess(*this, E->getNameLoc(), Entity);
1558 }
1559 
1560 /// Perform access-control checking on a previously-unresolved member
1561 /// access which has now been resolved to a member.
1562 Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
1563                                                      DeclAccessPair Found) {
1564   if (!getLangOpts().AccessControl ||
1565       Found.getAccess() == AS_public)
1566     return AR_accessible;
1567 
1568   QualType BaseType = E->getBaseType();
1569   if (E->isArrow())
1570     BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1571 
1572   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1573                       Found, BaseType);
1574   Entity.setDiag(diag::err_access) << E->getSourceRange();
1575 
1576   return CheckAccess(*this, E->getMemberLoc(), Entity);
1577 }
1578 
1579 /// Is the given member accessible for the purposes of deciding whether to
1580 /// define a special member function as deleted?
1581 bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
1582                                          DeclAccessPair Found,
1583                                          QualType ObjectType,
1584                                          SourceLocation Loc,
1585                                          const PartialDiagnostic &Diag) {
1586   // Fast path.
1587   if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1588     return true;
1589 
1590   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1591                       ObjectType);
1592 
1593   // Suppress diagnostics.
1594   Entity.setDiag(Diag);
1595 
1596   switch (CheckAccess(*this, Loc, Entity)) {
1597   case AR_accessible: return true;
1598   case AR_inaccessible: return false;
1599   case AR_dependent: llvm_unreachable("dependent for =delete computation");
1600   case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1601   }
1602   llvm_unreachable("bad access result");
1603 }
1604 
1605 Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
1606                                                CXXDestructorDecl *Dtor,
1607                                                const PartialDiagnostic &PDiag,
1608                                                QualType ObjectTy) {
1609   if (!getLangOpts().AccessControl)
1610     return AR_accessible;
1611 
1612   // There's never a path involved when checking implicit destructor access.
1613   AccessSpecifier Access = Dtor->getAccess();
1614   if (Access == AS_public)
1615     return AR_accessible;
1616 
1617   CXXRecordDecl *NamingClass = Dtor->getParent();
1618   if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1619 
1620   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1621                       DeclAccessPair::make(Dtor, Access),
1622                       ObjectTy);
1623   Entity.setDiag(PDiag); // TODO: avoid copy
1624 
1625   return CheckAccess(*this, Loc, Entity);
1626 }
1627 
1628 /// Checks access to a constructor.
1629 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1630                                                 CXXConstructorDecl *Constructor,
1631                                                 DeclAccessPair Found,
1632                                                 const InitializedEntity &Entity,
1633                                                 bool IsCopyBindingRefToTemp) {
1634   if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1635     return AR_accessible;
1636 
1637   PartialDiagnostic PD(PDiag());
1638   switch (Entity.getKind()) {
1639   default:
1640     PD = PDiag(IsCopyBindingRefToTemp
1641                  ? diag::ext_rvalue_to_reference_access_ctor
1642                  : diag::err_access_ctor);
1643 
1644     break;
1645 
1646   case InitializedEntity::EK_Base:
1647     PD = PDiag(diag::err_access_base_ctor);
1648     PD << Entity.isInheritedVirtualBase()
1649        << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1650     break;
1651 
1652   case InitializedEntity::EK_Member: {
1653     const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1654     PD = PDiag(diag::err_access_field_ctor);
1655     PD << Field->getType() << getSpecialMember(Constructor);
1656     break;
1657   }
1658 
1659   case InitializedEntity::EK_LambdaCapture: {
1660     StringRef VarName = Entity.getCapturedVarName();
1661     PD = PDiag(diag::err_access_lambda_capture);
1662     PD << VarName << Entity.getType() << getSpecialMember(Constructor);
1663     break;
1664   }
1665 
1666   }
1667 
1668   return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1669 }
1670 
1671 /// Checks access to a constructor.
1672 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1673                                                 CXXConstructorDecl *Constructor,
1674                                                 DeclAccessPair Found,
1675                                                 const InitializedEntity &Entity,
1676                                                 const PartialDiagnostic &PD) {
1677   if (!getLangOpts().AccessControl ||
1678       Found.getAccess() == AS_public)
1679     return AR_accessible;
1680 
1681   CXXRecordDecl *NamingClass = Constructor->getParent();
1682 
1683   // Initializing a base sub-object is an instance method call on an
1684   // object of the derived class.  Otherwise, we have an instance method
1685   // call on an object of the constructed type.
1686   //
1687   // FIXME: If we have a parent, we're initializing the base class subobject
1688   // in aggregate initialization. It's not clear whether the object class
1689   // should be the base class or the derived class in that case.
1690   CXXRecordDecl *ObjectClass;
1691   if ((Entity.getKind() == InitializedEntity::EK_Base ||
1692        Entity.getKind() == InitializedEntity::EK_Delegating) &&
1693       !Entity.getParent()) {
1694     ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1695   } else if (auto *Shadow =
1696                  dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1697     // If we're using an inheriting constructor to construct an object,
1698     // the object class is the derived class, not the base class.
1699     ObjectClass = Shadow->getParent();
1700   } else {
1701     ObjectClass = NamingClass;
1702   }
1703 
1704   AccessTarget AccessEntity(
1705       Context, AccessTarget::Member, NamingClass,
1706       DeclAccessPair::make(Constructor, Found.getAccess()),
1707       Context.getTypeDeclType(ObjectClass));
1708   AccessEntity.setDiag(PD);
1709 
1710   return CheckAccess(*this, UseLoc, AccessEntity);
1711 }
1712 
1713 /// Checks access to an overloaded operator new or delete.
1714 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
1715                                                SourceRange PlacementRange,
1716                                                CXXRecordDecl *NamingClass,
1717                                                DeclAccessPair Found,
1718                                                bool Diagnose) {
1719   if (!getLangOpts().AccessControl ||
1720       !NamingClass ||
1721       Found.getAccess() == AS_public)
1722     return AR_accessible;
1723 
1724   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1725                       QualType());
1726   if (Diagnose)
1727     Entity.setDiag(diag::err_access)
1728       << PlacementRange;
1729 
1730   return CheckAccess(*this, OpLoc, Entity);
1731 }
1732 
1733 /// Checks access to a member.
1734 Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
1735                                            CXXRecordDecl *NamingClass,
1736                                            DeclAccessPair Found) {
1737   if (!getLangOpts().AccessControl ||
1738       !NamingClass ||
1739       Found.getAccess() == AS_public)
1740     return AR_accessible;
1741 
1742   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1743                       Found, QualType());
1744 
1745   return CheckAccess(*this, UseLoc, Entity);
1746 }
1747 
1748 /// Checks implicit access to a member in a structured binding.
1749 Sema::AccessResult
1750 Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
1751                                          CXXRecordDecl *DecomposedClass,
1752                                          DeclAccessPair Field) {
1753   if (!getLangOpts().AccessControl ||
1754       Field.getAccess() == AS_public)
1755     return AR_accessible;
1756 
1757   AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1758                       Context.getRecordType(DecomposedClass));
1759   Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1760 
1761   return CheckAccess(*this, UseLoc, Entity);
1762 }
1763 
1764 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1765                                                    Expr *ObjectExpr,
1766                                                    const SourceRange &Range,
1767                                                    DeclAccessPair Found) {
1768   if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1769     return AR_accessible;
1770 
1771   const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1772   CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1773 
1774   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1775                       ObjectExpr->getType());
1776   Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1777 
1778   return CheckAccess(*this, OpLoc, Entity);
1779 }
1780 
1781 /// Checks access to an overloaded member operator, including
1782 /// conversion operators.
1783 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1784                                                    Expr *ObjectExpr,
1785                                                    Expr *ArgExpr,
1786                                                    DeclAccessPair Found) {
1787   return CheckMemberOperatorAccess(
1788       OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1789       Found);
1790 }
1791 
1792 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1793                                                    Expr *ObjectExpr,
1794                                                    ArrayRef<Expr *> ArgExprs,
1795                                                    DeclAccessPair FoundDecl) {
1796   SourceRange R;
1797   if (!ArgExprs.empty()) {
1798     R = SourceRange(ArgExprs.front()->getBeginLoc(),
1799                     ArgExprs.back()->getEndLoc());
1800   }
1801 
1802   return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1803 }
1804 
1805 /// Checks access to the target of a friend declaration.
1806 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
1807   assert(isa<CXXMethodDecl>(target->getAsFunction()));
1808 
1809   // Friendship lookup is a redeclaration lookup, so there's never an
1810   // inheritance path modifying access.
1811   AccessSpecifier access = target->getAccess();
1812 
1813   if (!getLangOpts().AccessControl || access == AS_public)
1814     return AR_accessible;
1815 
1816   CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1817 
1818   AccessTarget entity(Context, AccessTarget::Member,
1819                       cast<CXXRecordDecl>(target->getDeclContext()),
1820                       DeclAccessPair::make(target, access),
1821                       /*no instance context*/ QualType());
1822   entity.setDiag(diag::err_access_friend_function)
1823       << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1824                                  : method->getNameInfo().getSourceRange());
1825 
1826   // We need to bypass delayed-diagnostics because we might be called
1827   // while the ParsingDeclarator is active.
1828   EffectiveContext EC(CurContext);
1829   switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1830   case ::AR_accessible: return Sema::AR_accessible;
1831   case ::AR_inaccessible: return Sema::AR_inaccessible;
1832   case ::AR_dependent: return Sema::AR_dependent;
1833   }
1834   llvm_unreachable("invalid access result");
1835 }
1836 
1837 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
1838                                                     DeclAccessPair Found) {
1839   if (!getLangOpts().AccessControl ||
1840       Found.getAccess() == AS_none ||
1841       Found.getAccess() == AS_public)
1842     return AR_accessible;
1843 
1844   OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1845   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1846 
1847   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1848                       /*no instance context*/ QualType());
1849   Entity.setDiag(diag::err_access)
1850     << Ovl->getSourceRange();
1851 
1852   return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1853 }
1854 
1855 /// Checks access for a hierarchy conversion.
1856 ///
1857 /// \param ForceCheck true if this check should be performed even if access
1858 ///     control is disabled;  some things rely on this for semantics
1859 /// \param ForceUnprivileged true if this check should proceed as if the
1860 ///     context had no special privileges
1861 Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
1862                                               QualType Base,
1863                                               QualType Derived,
1864                                               const CXXBasePath &Path,
1865                                               unsigned DiagID,
1866                                               bool ForceCheck,
1867                                               bool ForceUnprivileged) {
1868   if (!ForceCheck && !getLangOpts().AccessControl)
1869     return AR_accessible;
1870 
1871   if (Path.Access == AS_public)
1872     return AR_accessible;
1873 
1874   CXXRecordDecl *BaseD, *DerivedD;
1875   BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1876   DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1877 
1878   AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1879                       Path.Access);
1880   if (DiagID)
1881     Entity.setDiag(DiagID) << Derived << Base;
1882 
1883   if (ForceUnprivileged) {
1884     switch (CheckEffectiveAccess(*this, EffectiveContext(),
1885                                  AccessLoc, Entity)) {
1886     case ::AR_accessible: return Sema::AR_accessible;
1887     case ::AR_inaccessible: return Sema::AR_inaccessible;
1888     case ::AR_dependent: return Sema::AR_dependent;
1889     }
1890     llvm_unreachable("unexpected result from CheckEffectiveAccess");
1891   }
1892   return CheckAccess(*this, AccessLoc, Entity);
1893 }
1894 
1895 /// Checks access to all the declarations in the given result set.
1896 void Sema::CheckLookupAccess(const LookupResult &R) {
1897   assert(getLangOpts().AccessControl
1898          && "performing access check without access control");
1899   assert(R.getNamingClass() && "performing access check without naming class");
1900 
1901   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1902     if (I.getAccess() != AS_public) {
1903       AccessTarget Entity(Context, AccessedEntity::Member,
1904                           R.getNamingClass(), I.getPair(),
1905                           R.getBaseObjectType());
1906       Entity.setDiag(diag::err_access);
1907       CheckAccess(*this, R.getNameLoc(), Entity);
1908     }
1909   }
1910 }
1911 
1912 /// Checks access to Target from the given class. The check will take access
1913 /// specifiers into account, but no member access expressions and such.
1914 ///
1915 /// \param Target the declaration to check if it can be accessed
1916 /// \param NamingClass the class in which the lookup was started.
1917 /// \param BaseType type of the left side of member access expression.
1918 ///        \p BaseType and \p NamingClass are used for C++ access control.
1919 ///        Depending on the lookup case, they should be set to the following:
1920 ///        - lhs.target (member access without a qualifier):
1921 ///          \p BaseType and \p NamingClass are both the type of 'lhs'.
1922 ///        - lhs.X::target (member access with a qualifier):
1923 ///          BaseType is the type of 'lhs', NamingClass is 'X'
1924 ///        - X::target (qualified lookup without member access):
1925 ///          BaseType is null, NamingClass is 'X'.
1926 ///        - target (unqualified lookup).
1927 ///          BaseType is null, NamingClass is the parent class of 'target'.
1928 /// \return true if the Target is accessible from the Class, false otherwise.
1929 bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
1930                               QualType BaseType) {
1931   // Perform the C++ accessibility checks first.
1932   if (Target->isCXXClassMember() && NamingClass) {
1933     if (!getLangOpts().CPlusPlus)
1934       return false;
1935     // The unprivileged access is AS_none as we don't know how the member was
1936     // accessed, which is described by the access in DeclAccessPair.
1937     // `IsAccessible` will examine the actual access of Target (i.e.
1938     // Decl->getAccess()) when calculating the access.
1939     AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1940                         DeclAccessPair::make(Target, AS_none), BaseType);
1941     EffectiveContext EC(CurContext);
1942     return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1943   }
1944 
1945   if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1946     // @public and @package ivars are always accessible.
1947     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1948         Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1949       return true;
1950 
1951     // If we are inside a class or category implementation, determine the
1952     // interface we're in.
1953     ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1954     if (ObjCMethodDecl *MD = getCurMethodDecl())
1955       ClassOfMethodDecl =  MD->getClassInterface();
1956     else if (FunctionDecl *FD = getCurFunctionDecl()) {
1957       if (ObjCImplDecl *Impl
1958             = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1959         if (ObjCImplementationDecl *IMPD
1960               = dyn_cast<ObjCImplementationDecl>(Impl))
1961           ClassOfMethodDecl = IMPD->getClassInterface();
1962         else if (ObjCCategoryImplDecl* CatImplClass
1963                    = dyn_cast<ObjCCategoryImplDecl>(Impl))
1964           ClassOfMethodDecl = CatImplClass->getClassInterface();
1965       }
1966     }
1967 
1968     // If we're not in an interface, this ivar is inaccessible.
1969     if (!ClassOfMethodDecl)
1970       return false;
1971 
1972     // If we're inside the same interface that owns the ivar, we're fine.
1973     if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1974       return true;
1975 
1976     // If the ivar is private, it's inaccessible.
1977     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1978       return false;
1979 
1980     return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1981   }
1982 
1983   return true;
1984 }
1985