clang API Documentation
00001 //===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides Sema routines for C++ access control semantics. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Sema/SemaInternal.h" 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/CXXInheritance.h" 00017 #include "clang/AST/DeclCXX.h" 00018 #include "clang/AST/DeclFriend.h" 00019 #include "clang/AST/DeclObjC.h" 00020 #include "clang/AST/DependentDiagnostic.h" 00021 #include "clang/AST/ExprCXX.h" 00022 #include "clang/Sema/DelayedDiagnostic.h" 00023 #include "clang/Sema/Initialization.h" 00024 #include "clang/Sema/Lookup.h" 00025 00026 using namespace clang; 00027 using namespace sema; 00028 00029 /// A copy of Sema's enum without AR_delayed. 00030 enum AccessResult { 00031 AR_accessible, 00032 AR_inaccessible, 00033 AR_dependent 00034 }; 00035 00036 /// SetMemberAccessSpecifier - Set the access specifier of a member. 00037 /// Returns true on error (when the previous member decl access specifier 00038 /// is different from the new member decl access specifier). 00039 bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, 00040 NamedDecl *PrevMemberDecl, 00041 AccessSpecifier LexicalAS) { 00042 if (!PrevMemberDecl) { 00043 // Use the lexical access specifier. 00044 MemberDecl->setAccess(LexicalAS); 00045 return false; 00046 } 00047 00048 // C++ [class.access.spec]p3: When a member is redeclared its access 00049 // specifier must be same as its initial declaration. 00050 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) { 00051 Diag(MemberDecl->getLocation(), 00052 diag::err_class_redeclared_with_different_access) 00053 << MemberDecl << LexicalAS; 00054 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration) 00055 << PrevMemberDecl << PrevMemberDecl->getAccess(); 00056 00057 MemberDecl->setAccess(LexicalAS); 00058 return true; 00059 } 00060 00061 MemberDecl->setAccess(PrevMemberDecl->getAccess()); 00062 return false; 00063 } 00064 00065 static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) { 00066 DeclContext *DC = D->getDeclContext(); 00067 00068 // This can only happen at top: enum decls only "publish" their 00069 // immediate members. 00070 if (isa<EnumDecl>(DC)) 00071 DC = cast<EnumDecl>(DC)->getDeclContext(); 00072 00073 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC); 00074 while (DeclaringClass->isAnonymousStructOrUnion()) 00075 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext()); 00076 return DeclaringClass; 00077 } 00078 00079 namespace { 00080 struct EffectiveContext { 00081 EffectiveContext() : Inner(nullptr), Dependent(false) {} 00082 00083 explicit EffectiveContext(DeclContext *DC) 00084 : Inner(DC), 00085 Dependent(DC->isDependentContext()) { 00086 00087 // C++11 [class.access.nest]p1: 00088 // A nested class is a member and as such has the same access 00089 // rights as any other member. 00090 // C++11 [class.access]p2: 00091 // A member of a class can also access all the names to which 00092 // the class has access. A local class of a member function 00093 // may access the same names that the member function itself 00094 // may access. 00095 // This almost implies that the privileges of nesting are transitive. 00096 // Technically it says nothing about the local classes of non-member 00097 // functions (which can gain privileges through friendship), but we 00098 // take that as an oversight. 00099 while (true) { 00100 // We want to add canonical declarations to the EC lists for 00101 // simplicity of checking, but we need to walk up through the 00102 // actual current DC chain. Otherwise, something like a local 00103 // extern or friend which happens to be the canonical 00104 // declaration will really mess us up. 00105 00106 if (isa<CXXRecordDecl>(DC)) { 00107 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); 00108 Records.push_back(Record->getCanonicalDecl()); 00109 DC = Record->getDeclContext(); 00110 } else if (isa<FunctionDecl>(DC)) { 00111 FunctionDecl *Function = cast<FunctionDecl>(DC); 00112 Functions.push_back(Function->getCanonicalDecl()); 00113 if (Function->getFriendObjectKind()) 00114 DC = Function->getLexicalDeclContext(); 00115 else 00116 DC = Function->getDeclContext(); 00117 } else if (DC->isFileContext()) { 00118 break; 00119 } else { 00120 DC = DC->getParent(); 00121 } 00122 } 00123 } 00124 00125 bool isDependent() const { return Dependent; } 00126 00127 bool includesClass(const CXXRecordDecl *R) const { 00128 R = R->getCanonicalDecl(); 00129 return std::find(Records.begin(), Records.end(), R) 00130 != Records.end(); 00131 } 00132 00133 /// Retrieves the innermost "useful" context. Can be null if we're 00134 /// doing access-control without privileges. 00135 DeclContext *getInnerContext() const { 00136 return Inner; 00137 } 00138 00139 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator; 00140 00141 DeclContext *Inner; 00142 SmallVector<FunctionDecl*, 4> Functions; 00143 SmallVector<CXXRecordDecl*, 4> Records; 00144 bool Dependent; 00145 }; 00146 00147 /// Like sema::AccessedEntity, but kindly lets us scribble all over 00148 /// it. 00149 struct AccessTarget : public AccessedEntity { 00150 AccessTarget(const AccessedEntity &Entity) 00151 : AccessedEntity(Entity) { 00152 initialize(); 00153 } 00154 00155 AccessTarget(ASTContext &Context, 00156 MemberNonce _, 00157 CXXRecordDecl *NamingClass, 00158 DeclAccessPair FoundDecl, 00159 QualType BaseObjectType) 00160 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass, 00161 FoundDecl, BaseObjectType) { 00162 initialize(); 00163 } 00164 00165 AccessTarget(ASTContext &Context, 00166 BaseNonce _, 00167 CXXRecordDecl *BaseClass, 00168 CXXRecordDecl *DerivedClass, 00169 AccessSpecifier Access) 00170 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass, 00171 Access) { 00172 initialize(); 00173 } 00174 00175 bool isInstanceMember() const { 00176 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember()); 00177 } 00178 00179 bool hasInstanceContext() const { 00180 return HasInstanceContext; 00181 } 00182 00183 class SavedInstanceContext { 00184 public: 00185 ~SavedInstanceContext() { 00186 Target.HasInstanceContext = Has; 00187 } 00188 00189 private: 00190 friend struct AccessTarget; 00191 explicit SavedInstanceContext(AccessTarget &Target) 00192 : Target(Target), Has(Target.HasInstanceContext) {} 00193 AccessTarget &Target; 00194 bool Has; 00195 }; 00196 00197 SavedInstanceContext saveInstanceContext() { 00198 return SavedInstanceContext(*this); 00199 } 00200 00201 void suppressInstanceContext() { 00202 HasInstanceContext = false; 00203 } 00204 00205 const CXXRecordDecl *resolveInstanceContext(Sema &S) const { 00206 assert(HasInstanceContext); 00207 if (CalculatedInstanceContext) 00208 return InstanceContext; 00209 00210 CalculatedInstanceContext = true; 00211 DeclContext *IC = S.computeDeclContext(getBaseObjectType()); 00212 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() 00213 : nullptr); 00214 return InstanceContext; 00215 } 00216 00217 const CXXRecordDecl *getDeclaringClass() const { 00218 return DeclaringClass; 00219 } 00220 00221 /// The "effective" naming class is the canonical non-anonymous 00222 /// class containing the actual naming class. 00223 const CXXRecordDecl *getEffectiveNamingClass() const { 00224 const CXXRecordDecl *namingClass = getNamingClass(); 00225 while (namingClass->isAnonymousStructOrUnion()) 00226 namingClass = cast<CXXRecordDecl>(namingClass->getParent()); 00227 return namingClass->getCanonicalDecl(); 00228 } 00229 00230 private: 00231 void initialize() { 00232 HasInstanceContext = (isMemberAccess() && 00233 !getBaseObjectType().isNull() && 00234 getTargetDecl()->isCXXInstanceMember()); 00235 CalculatedInstanceContext = false; 00236 InstanceContext = nullptr; 00237 00238 if (isMemberAccess()) 00239 DeclaringClass = FindDeclaringClass(getTargetDecl()); 00240 else 00241 DeclaringClass = getBaseClass(); 00242 DeclaringClass = DeclaringClass->getCanonicalDecl(); 00243 } 00244 00245 bool HasInstanceContext : 1; 00246 mutable bool CalculatedInstanceContext : 1; 00247 mutable const CXXRecordDecl *InstanceContext; 00248 const CXXRecordDecl *DeclaringClass; 00249 }; 00250 00251 } 00252 00253 /// Checks whether one class might instantiate to the other. 00254 static bool MightInstantiateTo(const CXXRecordDecl *From, 00255 const CXXRecordDecl *To) { 00256 // Declaration names are always preserved by instantiation. 00257 if (From->getDeclName() != To->getDeclName()) 00258 return false; 00259 00260 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext(); 00261 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext(); 00262 if (FromDC == ToDC) return true; 00263 if (FromDC->isFileContext() || ToDC->isFileContext()) return false; 00264 00265 // Be conservative. 00266 return true; 00267 } 00268 00269 /// Checks whether one class is derived from another, inclusively. 00270 /// Properly indicates when it couldn't be determined due to 00271 /// dependence. 00272 /// 00273 /// This should probably be donated to AST or at least Sema. 00274 static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, 00275 const CXXRecordDecl *Target) { 00276 assert(Derived->getCanonicalDecl() == Derived); 00277 assert(Target->getCanonicalDecl() == Target); 00278 00279 if (Derived == Target) return AR_accessible; 00280 00281 bool CheckDependent = Derived->isDependentContext(); 00282 if (CheckDependent && MightInstantiateTo(Derived, Target)) 00283 return AR_dependent; 00284 00285 AccessResult OnFailure = AR_inaccessible; 00286 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack 00287 00288 while (true) { 00289 if (Derived->isDependentContext() && !Derived->hasDefinition()) 00290 return AR_dependent; 00291 00292 for (const auto &I : Derived->bases()) { 00293 const CXXRecordDecl *RD; 00294 00295 QualType T = I.getType(); 00296 if (const RecordType *RT = T->getAs<RecordType>()) { 00297 RD = cast<CXXRecordDecl>(RT->getDecl()); 00298 } else if (const InjectedClassNameType *IT 00299 = T->getAs<InjectedClassNameType>()) { 00300 RD = IT->getDecl(); 00301 } else { 00302 assert(T->isDependentType() && "non-dependent base wasn't a record?"); 00303 OnFailure = AR_dependent; 00304 continue; 00305 } 00306 00307 RD = RD->getCanonicalDecl(); 00308 if (RD == Target) return AR_accessible; 00309 if (CheckDependent && MightInstantiateTo(RD, Target)) 00310 OnFailure = AR_dependent; 00311 00312 Queue.push_back(RD); 00313 } 00314 00315 if (Queue.empty()) break; 00316 00317 Derived = Queue.pop_back_val(); 00318 } 00319 00320 return OnFailure; 00321 } 00322 00323 00324 static bool MightInstantiateTo(Sema &S, DeclContext *Context, 00325 DeclContext *Friend) { 00326 if (Friend == Context) 00327 return true; 00328 00329 assert(!Friend->isDependentContext() && 00330 "can't handle friends with dependent contexts here"); 00331 00332 if (!Context->isDependentContext()) 00333 return false; 00334 00335 if (Friend->isFileContext()) 00336 return false; 00337 00338 // TODO: this is very conservative 00339 return true; 00340 } 00341 00342 // Asks whether the type in 'context' can ever instantiate to the type 00343 // in 'friend'. 00344 static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) { 00345 if (Friend == Context) 00346 return true; 00347 00348 if (!Friend->isDependentType() && !Context->isDependentType()) 00349 return false; 00350 00351 // TODO: this is very conservative. 00352 return true; 00353 } 00354 00355 static bool MightInstantiateTo(Sema &S, 00356 FunctionDecl *Context, 00357 FunctionDecl *Friend) { 00358 if (Context->getDeclName() != Friend->getDeclName()) 00359 return false; 00360 00361 if (!MightInstantiateTo(S, 00362 Context->getDeclContext(), 00363 Friend->getDeclContext())) 00364 return false; 00365 00366 CanQual<FunctionProtoType> FriendTy 00367 = S.Context.getCanonicalType(Friend->getType()) 00368 ->getAs<FunctionProtoType>(); 00369 CanQual<FunctionProtoType> ContextTy 00370 = S.Context.getCanonicalType(Context->getType()) 00371 ->getAs<FunctionProtoType>(); 00372 00373 // There isn't any way that I know of to add qualifiers 00374 // during instantiation. 00375 if (FriendTy.getQualifiers() != ContextTy.getQualifiers()) 00376 return false; 00377 00378 if (FriendTy->getNumParams() != ContextTy->getNumParams()) 00379 return false; 00380 00381 if (!MightInstantiateTo(S, ContextTy->getReturnType(), 00382 FriendTy->getReturnType())) 00383 return false; 00384 00385 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I) 00386 if (!MightInstantiateTo(S, ContextTy->getParamType(I), 00387 FriendTy->getParamType(I))) 00388 return false; 00389 00390 return true; 00391 } 00392 00393 static bool MightInstantiateTo(Sema &S, 00394 FunctionTemplateDecl *Context, 00395 FunctionTemplateDecl *Friend) { 00396 return MightInstantiateTo(S, 00397 Context->getTemplatedDecl(), 00398 Friend->getTemplatedDecl()); 00399 } 00400 00401 static AccessResult MatchesFriend(Sema &S, 00402 const EffectiveContext &EC, 00403 const CXXRecordDecl *Friend) { 00404 if (EC.includesClass(Friend)) 00405 return AR_accessible; 00406 00407 if (EC.isDependent()) { 00408 CanQualType FriendTy 00409 = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend)); 00410 00411 for (EffectiveContext::record_iterator 00412 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 00413 CanQualType ContextTy 00414 = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I)); 00415 if (MightInstantiateTo(S, ContextTy, FriendTy)) 00416 return AR_dependent; 00417 } 00418 } 00419 00420 return AR_inaccessible; 00421 } 00422 00423 static AccessResult MatchesFriend(Sema &S, 00424 const EffectiveContext &EC, 00425 CanQualType Friend) { 00426 if (const RecordType *RT = Friend->getAs<RecordType>()) 00427 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl())); 00428 00429 // TODO: we can do better than this 00430 if (Friend->isDependentType()) 00431 return AR_dependent; 00432 00433 return AR_inaccessible; 00434 } 00435 00436 /// Determines whether the given friend class template matches 00437 /// anything in the effective context. 00438 static AccessResult MatchesFriend(Sema &S, 00439 const EffectiveContext &EC, 00440 ClassTemplateDecl *Friend) { 00441 AccessResult OnFailure = AR_inaccessible; 00442 00443 // Check whether the friend is the template of a class in the 00444 // context chain. 00445 for (SmallVectorImpl<CXXRecordDecl*>::const_iterator 00446 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 00447 CXXRecordDecl *Record = *I; 00448 00449 // Figure out whether the current class has a template: 00450 ClassTemplateDecl *CTD; 00451 00452 // A specialization of the template... 00453 if (isa<ClassTemplateSpecializationDecl>(Record)) { 00454 CTD = cast<ClassTemplateSpecializationDecl>(Record) 00455 ->getSpecializedTemplate(); 00456 00457 // ... or the template pattern itself. 00458 } else { 00459 CTD = Record->getDescribedClassTemplate(); 00460 if (!CTD) continue; 00461 } 00462 00463 // It's a match. 00464 if (Friend == CTD->getCanonicalDecl()) 00465 return AR_accessible; 00466 00467 // If the context isn't dependent, it can't be a dependent match. 00468 if (!EC.isDependent()) 00469 continue; 00470 00471 // If the template names don't match, it can't be a dependent 00472 // match. 00473 if (CTD->getDeclName() != Friend->getDeclName()) 00474 continue; 00475 00476 // If the class's context can't instantiate to the friend's 00477 // context, it can't be a dependent match. 00478 if (!MightInstantiateTo(S, CTD->getDeclContext(), 00479 Friend->getDeclContext())) 00480 continue; 00481 00482 // Otherwise, it's a dependent match. 00483 OnFailure = AR_dependent; 00484 } 00485 00486 return OnFailure; 00487 } 00488 00489 /// Determines whether the given friend function matches anything in 00490 /// the effective context. 00491 static AccessResult MatchesFriend(Sema &S, 00492 const EffectiveContext &EC, 00493 FunctionDecl *Friend) { 00494 AccessResult OnFailure = AR_inaccessible; 00495 00496 for (SmallVectorImpl<FunctionDecl*>::const_iterator 00497 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 00498 if (Friend == *I) 00499 return AR_accessible; 00500 00501 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend)) 00502 OnFailure = AR_dependent; 00503 } 00504 00505 return OnFailure; 00506 } 00507 00508 /// Determines whether the given friend function template matches 00509 /// anything in the effective context. 00510 static AccessResult MatchesFriend(Sema &S, 00511 const EffectiveContext &EC, 00512 FunctionTemplateDecl *Friend) { 00513 if (EC.Functions.empty()) return AR_inaccessible; 00514 00515 AccessResult OnFailure = AR_inaccessible; 00516 00517 for (SmallVectorImpl<FunctionDecl*>::const_iterator 00518 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 00519 00520 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate(); 00521 if (!FTD) 00522 FTD = (*I)->getDescribedFunctionTemplate(); 00523 if (!FTD) 00524 continue; 00525 00526 FTD = FTD->getCanonicalDecl(); 00527 00528 if (Friend == FTD) 00529 return AR_accessible; 00530 00531 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend)) 00532 OnFailure = AR_dependent; 00533 } 00534 00535 return OnFailure; 00536 } 00537 00538 /// Determines whether the given friend declaration matches anything 00539 /// in the effective context. 00540 static AccessResult MatchesFriend(Sema &S, 00541 const EffectiveContext &EC, 00542 FriendDecl *FriendD) { 00543 // Whitelist accesses if there's an invalid or unsupported friend 00544 // declaration. 00545 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend()) 00546 return AR_accessible; 00547 00548 if (TypeSourceInfo *T = FriendD->getFriendType()) 00549 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified()); 00550 00551 NamedDecl *Friend 00552 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl()); 00553 00554 // FIXME: declarations with dependent or templated scope. 00555 00556 if (isa<ClassTemplateDecl>(Friend)) 00557 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend)); 00558 00559 if (isa<FunctionTemplateDecl>(Friend)) 00560 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend)); 00561 00562 if (isa<CXXRecordDecl>(Friend)) 00563 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend)); 00564 00565 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind"); 00566 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend)); 00567 } 00568 00569 static AccessResult GetFriendKind(Sema &S, 00570 const EffectiveContext &EC, 00571 const CXXRecordDecl *Class) { 00572 AccessResult OnFailure = AR_inaccessible; 00573 00574 // Okay, check friends. 00575 for (auto *Friend : Class->friends()) { 00576 switch (MatchesFriend(S, EC, Friend)) { 00577 case AR_accessible: 00578 return AR_accessible; 00579 00580 case AR_inaccessible: 00581 continue; 00582 00583 case AR_dependent: 00584 OnFailure = AR_dependent; 00585 break; 00586 } 00587 } 00588 00589 // That's it, give up. 00590 return OnFailure; 00591 } 00592 00593 namespace { 00594 00595 /// A helper class for checking for a friend which will grant access 00596 /// to a protected instance member. 00597 struct ProtectedFriendContext { 00598 Sema &S; 00599 const EffectiveContext &EC; 00600 const CXXRecordDecl *NamingClass; 00601 bool CheckDependent; 00602 bool EverDependent; 00603 00604 /// The path down to the current base class. 00605 SmallVector<const CXXRecordDecl*, 20> CurPath; 00606 00607 ProtectedFriendContext(Sema &S, const EffectiveContext &EC, 00608 const CXXRecordDecl *InstanceContext, 00609 const CXXRecordDecl *NamingClass) 00610 : S(S), EC(EC), NamingClass(NamingClass), 00611 CheckDependent(InstanceContext->isDependentContext() || 00612 NamingClass->isDependentContext()), 00613 EverDependent(false) {} 00614 00615 /// Check classes in the current path for friendship, starting at 00616 /// the given index. 00617 bool checkFriendshipAlongPath(unsigned I) { 00618 assert(I < CurPath.size()); 00619 for (unsigned E = CurPath.size(); I != E; ++I) { 00620 switch (GetFriendKind(S, EC, CurPath[I])) { 00621 case AR_accessible: return true; 00622 case AR_inaccessible: continue; 00623 case AR_dependent: EverDependent = true; continue; 00624 } 00625 } 00626 return false; 00627 } 00628 00629 /// Perform a search starting at the given class. 00630 /// 00631 /// PrivateDepth is the index of the last (least derived) class 00632 /// along the current path such that a notional public member of 00633 /// the final class in the path would have access in that class. 00634 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) { 00635 // If we ever reach the naming class, check the current path for 00636 // friendship. We can also stop recursing because we obviously 00637 // won't find the naming class there again. 00638 if (Cur == NamingClass) 00639 return checkFriendshipAlongPath(PrivateDepth); 00640 00641 if (CheckDependent && MightInstantiateTo(Cur, NamingClass)) 00642 EverDependent = true; 00643 00644 // Recurse into the base classes. 00645 for (const auto &I : Cur->bases()) { 00646 // If this is private inheritance, then a public member of the 00647 // base will not have any access in classes derived from Cur. 00648 unsigned BasePrivateDepth = PrivateDepth; 00649 if (I.getAccessSpecifier() == AS_private) 00650 BasePrivateDepth = CurPath.size() - 1; 00651 00652 const CXXRecordDecl *RD; 00653 00654 QualType T = I.getType(); 00655 if (const RecordType *RT = T->getAs<RecordType>()) { 00656 RD = cast<CXXRecordDecl>(RT->getDecl()); 00657 } else if (const InjectedClassNameType *IT 00658 = T->getAs<InjectedClassNameType>()) { 00659 RD = IT->getDecl(); 00660 } else { 00661 assert(T->isDependentType() && "non-dependent base wasn't a record?"); 00662 EverDependent = true; 00663 continue; 00664 } 00665 00666 // Recurse. We don't need to clean up if this returns true. 00667 CurPath.push_back(RD); 00668 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth)) 00669 return true; 00670 CurPath.pop_back(); 00671 } 00672 00673 return false; 00674 } 00675 00676 bool findFriendship(const CXXRecordDecl *Cur) { 00677 assert(CurPath.empty()); 00678 CurPath.push_back(Cur); 00679 return findFriendship(Cur, 0); 00680 } 00681 }; 00682 } 00683 00684 /// Search for a class P that EC is a friend of, under the constraint 00685 /// InstanceContext <= P 00686 /// if InstanceContext exists, or else 00687 /// NamingClass <= P 00688 /// and with the additional restriction that a protected member of 00689 /// NamingClass would have some natural access in P, which implicitly 00690 /// imposes the constraint that P <= NamingClass. 00691 /// 00692 /// This isn't quite the condition laid out in the standard. 00693 /// Instead of saying that a notional protected member of NamingClass 00694 /// would have to have some natural access in P, it says the actual 00695 /// target has to have some natural access in P, which opens up the 00696 /// possibility that the target (which is not necessarily a member 00697 /// of NamingClass) might be more accessible along some path not 00698 /// passing through it. That's really a bad idea, though, because it 00699 /// introduces two problems: 00700 /// - Most importantly, it breaks encapsulation because you can 00701 /// access a forbidden base class's members by directly subclassing 00702 /// it elsewhere. 00703 /// - It also makes access substantially harder to compute because it 00704 /// breaks the hill-climbing algorithm: knowing that the target is 00705 /// accessible in some base class would no longer let you change 00706 /// the question solely to whether the base class is accessible, 00707 /// because the original target might have been more accessible 00708 /// because of crazy subclassing. 00709 /// So we don't implement that. 00710 static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, 00711 const CXXRecordDecl *InstanceContext, 00712 const CXXRecordDecl *NamingClass) { 00713 assert(InstanceContext == nullptr || 00714 InstanceContext->getCanonicalDecl() == InstanceContext); 00715 assert(NamingClass->getCanonicalDecl() == NamingClass); 00716 00717 // If we don't have an instance context, our constraints give us 00718 // that NamingClass <= P <= NamingClass, i.e. P == NamingClass. 00719 // This is just the usual friendship check. 00720 if (!InstanceContext) return GetFriendKind(S, EC, NamingClass); 00721 00722 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass); 00723 if (PRC.findFriendship(InstanceContext)) return AR_accessible; 00724 if (PRC.EverDependent) return AR_dependent; 00725 return AR_inaccessible; 00726 } 00727 00728 static AccessResult HasAccess(Sema &S, 00729 const EffectiveContext &EC, 00730 const CXXRecordDecl *NamingClass, 00731 AccessSpecifier Access, 00732 const AccessTarget &Target) { 00733 assert(NamingClass->getCanonicalDecl() == NamingClass && 00734 "declaration should be canonicalized before being passed here"); 00735 00736 if (Access == AS_public) return AR_accessible; 00737 assert(Access == AS_private || Access == AS_protected); 00738 00739 AccessResult OnFailure = AR_inaccessible; 00740 00741 for (EffectiveContext::record_iterator 00742 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 00743 // All the declarations in EC have been canonicalized, so pointer 00744 // equality from this point on will work fine. 00745 const CXXRecordDecl *ECRecord = *I; 00746 00747 // [B2] and [M2] 00748 if (Access == AS_private) { 00749 if (ECRecord == NamingClass) 00750 return AR_accessible; 00751 00752 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass)) 00753 OnFailure = AR_dependent; 00754 00755 // [B3] and [M3] 00756 } else { 00757 assert(Access == AS_protected); 00758 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) { 00759 case AR_accessible: break; 00760 case AR_inaccessible: continue; 00761 case AR_dependent: OnFailure = AR_dependent; continue; 00762 } 00763 00764 // C++ [class.protected]p1: 00765 // An additional access check beyond those described earlier in 00766 // [class.access] is applied when a non-static data member or 00767 // non-static member function is a protected member of its naming 00768 // class. As described earlier, access to a protected member is 00769 // granted because the reference occurs in a friend or member of 00770 // some class C. If the access is to form a pointer to member, 00771 // the nested-name-specifier shall name C or a class derived from 00772 // C. All other accesses involve a (possibly implicit) object 00773 // expression. In this case, the class of the object expression 00774 // shall be C or a class derived from C. 00775 // 00776 // We interpret this as a restriction on [M3]. 00777 00778 // In this part of the code, 'C' is just our context class ECRecord. 00779 00780 // These rules are different if we don't have an instance context. 00781 if (!Target.hasInstanceContext()) { 00782 // If it's not an instance member, these restrictions don't apply. 00783 if (!Target.isInstanceMember()) return AR_accessible; 00784 00785 // If it's an instance member, use the pointer-to-member rule 00786 // that the naming class has to be derived from the effective 00787 // context. 00788 00789 // Emulate a MSVC bug where the creation of pointer-to-member 00790 // to protected member of base class is allowed but only from 00791 // static member functions. 00792 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty()) 00793 if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front())) 00794 if (MD->isStatic()) return AR_accessible; 00795 00796 // Despite the standard's confident wording, there is a case 00797 // where you can have an instance member that's neither in a 00798 // pointer-to-member expression nor in a member access: when 00799 // it names a field in an unevaluated context that can't be an 00800 // implicit member. Pending clarification, we just apply the 00801 // same naming-class restriction here. 00802 // FIXME: we're probably not correctly adding the 00803 // protected-member restriction when we retroactively convert 00804 // an expression to being evaluated. 00805 00806 // We know that ECRecord derives from NamingClass. The 00807 // restriction says to check whether NamingClass derives from 00808 // ECRecord, but that's not really necessary: two distinct 00809 // classes can't be recursively derived from each other. So 00810 // along this path, we just need to check whether the classes 00811 // are equal. 00812 if (NamingClass == ECRecord) return AR_accessible; 00813 00814 // Otherwise, this context class tells us nothing; on to the next. 00815 continue; 00816 } 00817 00818 assert(Target.isInstanceMember()); 00819 00820 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 00821 if (!InstanceContext) { 00822 OnFailure = AR_dependent; 00823 continue; 00824 } 00825 00826 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) { 00827 case AR_accessible: return AR_accessible; 00828 case AR_inaccessible: continue; 00829 case AR_dependent: OnFailure = AR_dependent; continue; 00830 } 00831 } 00832 } 00833 00834 // [M3] and [B3] say that, if the target is protected in N, we grant 00835 // access if the access occurs in a friend or member of some class P 00836 // that's a subclass of N and where the target has some natural 00837 // access in P. The 'member' aspect is easy to handle because P 00838 // would necessarily be one of the effective-context records, and we 00839 // address that above. The 'friend' aspect is completely ridiculous 00840 // to implement because there are no restrictions at all on P 00841 // *unless* the [class.protected] restriction applies. If it does, 00842 // however, we should ignore whether the naming class is a friend, 00843 // and instead rely on whether any potential P is a friend. 00844 if (Access == AS_protected && Target.isInstanceMember()) { 00845 // Compute the instance context if possible. 00846 const CXXRecordDecl *InstanceContext = nullptr; 00847 if (Target.hasInstanceContext()) { 00848 InstanceContext = Target.resolveInstanceContext(S); 00849 if (!InstanceContext) return AR_dependent; 00850 } 00851 00852 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) { 00853 case AR_accessible: return AR_accessible; 00854 case AR_inaccessible: return OnFailure; 00855 case AR_dependent: return AR_dependent; 00856 } 00857 llvm_unreachable("impossible friendship kind"); 00858 } 00859 00860 switch (GetFriendKind(S, EC, NamingClass)) { 00861 case AR_accessible: return AR_accessible; 00862 case AR_inaccessible: return OnFailure; 00863 case AR_dependent: return AR_dependent; 00864 } 00865 00866 // Silence bogus warnings 00867 llvm_unreachable("impossible friendship kind"); 00868 } 00869 00870 /// Finds the best path from the naming class to the declaring class, 00871 /// taking friend declarations into account. 00872 /// 00873 /// C++0x [class.access.base]p5: 00874 /// A member m is accessible at the point R when named in class N if 00875 /// [M1] m as a member of N is public, or 00876 /// [M2] m as a member of N is private, and R occurs in a member or 00877 /// friend of class N, or 00878 /// [M3] m as a member of N is protected, and R occurs in a member or 00879 /// friend of class N, or in a member or friend of a class P 00880 /// derived from N, where m as a member of P is public, private, 00881 /// or protected, or 00882 /// [M4] there exists a base class B of N that is accessible at R, and 00883 /// m is accessible at R when named in class B. 00884 /// 00885 /// C++0x [class.access.base]p4: 00886 /// A base class B of N is accessible at R, if 00887 /// [B1] an invented public member of B would be a public member of N, or 00888 /// [B2] R occurs in a member or friend of class N, and an invented public 00889 /// member of B would be a private or protected member of N, or 00890 /// [B3] R occurs in a member or friend of a class P derived from N, and an 00891 /// invented public member of B would be a private or protected member 00892 /// of P, or 00893 /// [B4] there exists a class S such that B is a base class of S accessible 00894 /// at R and S is a base class of N accessible at R. 00895 /// 00896 /// Along a single inheritance path we can restate both of these 00897 /// iteratively: 00898 /// 00899 /// First, we note that M1-4 are equivalent to B1-4 if the member is 00900 /// treated as a notional base of its declaring class with inheritance 00901 /// access equivalent to the member's access. Therefore we need only 00902 /// ask whether a class B is accessible from a class N in context R. 00903 /// 00904 /// Let B_1 .. B_n be the inheritance path in question (i.e. where 00905 /// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of 00906 /// B_i). For i in 1..n, we will calculate ACAB(i), the access to the 00907 /// closest accessible base in the path: 00908 /// Access(a, b) = (* access on the base specifier from a to b *) 00909 /// Merge(a, forbidden) = forbidden 00910 /// Merge(a, private) = forbidden 00911 /// Merge(a, b) = min(a,b) 00912 /// Accessible(c, forbidden) = false 00913 /// Accessible(c, private) = (R is c) || IsFriend(c, R) 00914 /// Accessible(c, protected) = (R derived from c) || IsFriend(c, R) 00915 /// Accessible(c, public) = true 00916 /// ACAB(n) = public 00917 /// ACAB(i) = 00918 /// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in 00919 /// if Accessible(B_i, AccessToBase) then public else AccessToBase 00920 /// 00921 /// B is an accessible base of N at R iff ACAB(1) = public. 00922 /// 00923 /// \param FinalAccess the access of the "final step", or AS_public if 00924 /// there is no final step. 00925 /// \return null if friendship is dependent 00926 static CXXBasePath *FindBestPath(Sema &S, 00927 const EffectiveContext &EC, 00928 AccessTarget &Target, 00929 AccessSpecifier FinalAccess, 00930 CXXBasePaths &Paths) { 00931 // Derive the paths to the desired base. 00932 const CXXRecordDecl *Derived = Target.getNamingClass(); 00933 const CXXRecordDecl *Base = Target.getDeclaringClass(); 00934 00935 // FIXME: fail correctly when there are dependent paths. 00936 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base), 00937 Paths); 00938 assert(isDerived && "derived class not actually derived from base"); 00939 (void) isDerived; 00940 00941 CXXBasePath *BestPath = nullptr; 00942 00943 assert(FinalAccess != AS_none && "forbidden access after declaring class"); 00944 00945 bool AnyDependent = false; 00946 00947 // Derive the friend-modified access along each path. 00948 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end(); 00949 PI != PE; ++PI) { 00950 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext(); 00951 00952 // Walk through the path backwards. 00953 AccessSpecifier PathAccess = FinalAccess; 00954 CXXBasePath::iterator I = PI->end(), E = PI->begin(); 00955 while (I != E) { 00956 --I; 00957 00958 assert(PathAccess != AS_none); 00959 00960 // If the declaration is a private member of a base class, there 00961 // is no level of friendship in derived classes that can make it 00962 // accessible. 00963 if (PathAccess == AS_private) { 00964 PathAccess = AS_none; 00965 break; 00966 } 00967 00968 const CXXRecordDecl *NC = I->Class->getCanonicalDecl(); 00969 00970 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier(); 00971 PathAccess = std::max(PathAccess, BaseAccess); 00972 00973 switch (HasAccess(S, EC, NC, PathAccess, Target)) { 00974 case AR_inaccessible: break; 00975 case AR_accessible: 00976 PathAccess = AS_public; 00977 00978 // Future tests are not against members and so do not have 00979 // instance context. 00980 Target.suppressInstanceContext(); 00981 break; 00982 case AR_dependent: 00983 AnyDependent = true; 00984 goto Next; 00985 } 00986 } 00987 00988 // Note that we modify the path's Access field to the 00989 // friend-modified access. 00990 if (BestPath == nullptr || PathAccess < BestPath->Access) { 00991 BestPath = &*PI; 00992 BestPath->Access = PathAccess; 00993 00994 // Short-circuit if we found a public path. 00995 if (BestPath->Access == AS_public) 00996 return BestPath; 00997 } 00998 00999 Next: ; 01000 } 01001 01002 assert((!BestPath || BestPath->Access != AS_public) && 01003 "fell out of loop with public path"); 01004 01005 // We didn't find a public path, but at least one path was subject 01006 // to dependent friendship, so delay the check. 01007 if (AnyDependent) 01008 return nullptr; 01009 01010 return BestPath; 01011 } 01012 01013 /// Given that an entity has protected natural access, check whether 01014 /// access might be denied because of the protected member access 01015 /// restriction. 01016 /// 01017 /// \return true if a note was emitted 01018 static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, 01019 AccessTarget &Target) { 01020 // Only applies to instance accesses. 01021 if (!Target.isInstanceMember()) 01022 return false; 01023 01024 assert(Target.isMemberAccess()); 01025 01026 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass(); 01027 01028 for (EffectiveContext::record_iterator 01029 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 01030 const CXXRecordDecl *ECRecord = *I; 01031 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) { 01032 case AR_accessible: break; 01033 case AR_inaccessible: continue; 01034 case AR_dependent: continue; 01035 } 01036 01037 // The effective context is a subclass of the declaring class. 01038 // Check whether the [class.protected] restriction is limiting 01039 // access. 01040 01041 // To get this exactly right, this might need to be checked more 01042 // holistically; it's not necessarily the case that gaining 01043 // access here would grant us access overall. 01044 01045 NamedDecl *D = Target.getTargetDecl(); 01046 01047 // If we don't have an instance context, [class.protected] says the 01048 // naming class has to equal the context class. 01049 if (!Target.hasInstanceContext()) { 01050 // If it does, the restriction doesn't apply. 01051 if (NamingClass == ECRecord) continue; 01052 01053 // TODO: it would be great to have a fixit here, since this is 01054 // such an obvious error. 01055 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject) 01056 << S.Context.getTypeDeclType(ECRecord); 01057 return true; 01058 } 01059 01060 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 01061 assert(InstanceContext && "diagnosing dependent access"); 01062 01063 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) { 01064 case AR_accessible: continue; 01065 case AR_dependent: continue; 01066 case AR_inaccessible: 01067 break; 01068 } 01069 01070 // Okay, the restriction seems to be what's limiting us. 01071 01072 // Use a special diagnostic for constructors and destructors. 01073 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) || 01074 (isa<FunctionTemplateDecl>(D) && 01075 isa<CXXConstructorDecl>( 01076 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) { 01077 return S.Diag(D->getLocation(), 01078 diag::note_access_protected_restricted_ctordtor) 01079 << isa<CXXDestructorDecl>(D->getAsFunction()); 01080 } 01081 01082 // Otherwise, use the generic diagnostic. 01083 return S.Diag(D->getLocation(), 01084 diag::note_access_protected_restricted_object) 01085 << S.Context.getTypeDeclType(ECRecord); 01086 } 01087 01088 return false; 01089 } 01090 01091 /// We are unable to access a given declaration due to its direct 01092 /// access control; diagnose that. 01093 static void diagnoseBadDirectAccess(Sema &S, 01094 const EffectiveContext &EC, 01095 AccessTarget &entity) { 01096 assert(entity.isMemberAccess()); 01097 NamedDecl *D = entity.getTargetDecl(); 01098 01099 if (D->getAccess() == AS_protected && 01100 TryDiagnoseProtectedAccess(S, EC, entity)) 01101 return; 01102 01103 // Find an original declaration. 01104 while (D->isOutOfLine()) { 01105 NamedDecl *PrevDecl = nullptr; 01106 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 01107 PrevDecl = VD->getPreviousDecl(); 01108 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 01109 PrevDecl = FD->getPreviousDecl(); 01110 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) 01111 PrevDecl = TND->getPreviousDecl(); 01112 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 01113 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName()) 01114 break; 01115 PrevDecl = TD->getPreviousDecl(); 01116 } 01117 if (!PrevDecl) break; 01118 D = PrevDecl; 01119 } 01120 01121 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D); 01122 Decl *ImmediateChild; 01123 if (D->getDeclContext() == DeclaringClass) 01124 ImmediateChild = D; 01125 else { 01126 DeclContext *DC = D->getDeclContext(); 01127 while (DC->getParent() != DeclaringClass) 01128 DC = DC->getParent(); 01129 ImmediateChild = cast<Decl>(DC); 01130 } 01131 01132 // Check whether there's an AccessSpecDecl preceding this in the 01133 // chain of the DeclContext. 01134 bool isImplicit = true; 01135 for (const auto *I : DeclaringClass->decls()) { 01136 if (I == ImmediateChild) break; 01137 if (isa<AccessSpecDecl>(I)) { 01138 isImplicit = false; 01139 break; 01140 } 01141 } 01142 01143 S.Diag(D->getLocation(), diag::note_access_natural) 01144 << (unsigned) (D->getAccess() == AS_protected) 01145 << isImplicit; 01146 } 01147 01148 /// Diagnose the path which caused the given declaration or base class 01149 /// to become inaccessible. 01150 static void DiagnoseAccessPath(Sema &S, 01151 const EffectiveContext &EC, 01152 AccessTarget &entity) { 01153 // Save the instance context to preserve invariants. 01154 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext(); 01155 01156 // This basically repeats the main algorithm but keeps some more 01157 // information. 01158 01159 // The natural access so far. 01160 AccessSpecifier accessSoFar = AS_public; 01161 01162 // Check whether we have special rights to the declaring class. 01163 if (entity.isMemberAccess()) { 01164 NamedDecl *D = entity.getTargetDecl(); 01165 accessSoFar = D->getAccess(); 01166 const CXXRecordDecl *declaringClass = entity.getDeclaringClass(); 01167 01168 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) { 01169 // If the declaration is accessible when named in its declaring 01170 // class, then we must be constrained by the path. 01171 case AR_accessible: 01172 accessSoFar = AS_public; 01173 entity.suppressInstanceContext(); 01174 break; 01175 01176 case AR_inaccessible: 01177 if (accessSoFar == AS_private || 01178 declaringClass == entity.getEffectiveNamingClass()) 01179 return diagnoseBadDirectAccess(S, EC, entity); 01180 break; 01181 01182 case AR_dependent: 01183 llvm_unreachable("cannot diagnose dependent access"); 01184 } 01185 } 01186 01187 CXXBasePaths paths; 01188 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths); 01189 assert(path.Access != AS_public); 01190 01191 CXXBasePath::iterator i = path.end(), e = path.begin(); 01192 CXXBasePath::iterator constrainingBase = i; 01193 while (i != e) { 01194 --i; 01195 01196 assert(accessSoFar != AS_none && accessSoFar != AS_private); 01197 01198 // Is the entity accessible when named in the deriving class, as 01199 // modified by the base specifier? 01200 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl(); 01201 const CXXBaseSpecifier *base = i->Base; 01202 01203 // If the access to this base is worse than the access we have to 01204 // the declaration, remember it. 01205 AccessSpecifier baseAccess = base->getAccessSpecifier(); 01206 if (baseAccess > accessSoFar) { 01207 constrainingBase = i; 01208 accessSoFar = baseAccess; 01209 } 01210 01211 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) { 01212 case AR_inaccessible: break; 01213 case AR_accessible: 01214 accessSoFar = AS_public; 01215 entity.suppressInstanceContext(); 01216 constrainingBase = nullptr; 01217 break; 01218 case AR_dependent: 01219 llvm_unreachable("cannot diagnose dependent access"); 01220 } 01221 01222 // If this was private inheritance, but we don't have access to 01223 // the deriving class, we're done. 01224 if (accessSoFar == AS_private) { 01225 assert(baseAccess == AS_private); 01226 assert(constrainingBase == i); 01227 break; 01228 } 01229 } 01230 01231 // If we don't have a constraining base, the access failure must be 01232 // due to the original declaration. 01233 if (constrainingBase == path.end()) 01234 return diagnoseBadDirectAccess(S, EC, entity); 01235 01236 // We're constrained by inheritance, but we want to say 01237 // "declared private here" if we're diagnosing a hierarchy 01238 // conversion and this is the final step. 01239 unsigned diagnostic; 01240 if (entity.isMemberAccess() || 01241 constrainingBase + 1 != path.end()) { 01242 diagnostic = diag::note_access_constrained_by_path; 01243 } else { 01244 diagnostic = diag::note_access_natural; 01245 } 01246 01247 const CXXBaseSpecifier *base = constrainingBase->Base; 01248 01249 S.Diag(base->getSourceRange().getBegin(), diagnostic) 01250 << base->getSourceRange() 01251 << (base->getAccessSpecifier() == AS_protected) 01252 << (base->getAccessSpecifierAsWritten() == AS_none); 01253 01254 if (entity.isMemberAccess()) 01255 S.Diag(entity.getTargetDecl()->getLocation(), 01256 diag::note_member_declared_at); 01257 } 01258 01259 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, 01260 const EffectiveContext &EC, 01261 AccessTarget &Entity) { 01262 const CXXRecordDecl *NamingClass = Entity.getNamingClass(); 01263 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 01264 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr); 01265 01266 S.Diag(Loc, Entity.getDiag()) 01267 << (Entity.getAccess() == AS_protected) 01268 << (D ? D->getDeclName() : DeclarationName()) 01269 << S.Context.getTypeDeclType(NamingClass) 01270 << S.Context.getTypeDeclType(DeclaringClass); 01271 DiagnoseAccessPath(S, EC, Entity); 01272 } 01273 01274 /// MSVC has a bug where if during an using declaration name lookup, 01275 /// the declaration found is unaccessible (private) and that declaration 01276 /// was bring into scope via another using declaration whose target 01277 /// declaration is accessible (public) then no error is generated. 01278 /// Example: 01279 /// class A { 01280 /// public: 01281 /// int f(); 01282 /// }; 01283 /// class B : public A { 01284 /// private: 01285 /// using A::f; 01286 /// }; 01287 /// class C : public B { 01288 /// private: 01289 /// using B::f; 01290 /// }; 01291 /// 01292 /// Here, B::f is private so this should fail in Standard C++, but 01293 /// because B::f refers to A::f which is public MSVC accepts it. 01294 static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S, 01295 SourceLocation AccessLoc, 01296 AccessTarget &Entity) { 01297 if (UsingShadowDecl *Shadow = 01298 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) { 01299 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl(); 01300 if (Entity.getTargetDecl()->getAccess() == AS_private && 01301 (OrigDecl->getAccess() == AS_public || 01302 OrigDecl->getAccess() == AS_protected)) { 01303 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible) 01304 << Shadow->getUsingDecl()->getQualifiedNameAsString() 01305 << OrigDecl->getQualifiedNameAsString(); 01306 return true; 01307 } 01308 } 01309 return false; 01310 } 01311 01312 /// Determines whether the accessed entity is accessible. Public members 01313 /// have been weeded out by this point. 01314 static AccessResult IsAccessible(Sema &S, 01315 const EffectiveContext &EC, 01316 AccessTarget &Entity) { 01317 // Determine the actual naming class. 01318 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass(); 01319 01320 AccessSpecifier UnprivilegedAccess = Entity.getAccess(); 01321 assert(UnprivilegedAccess != AS_public && "public access not weeded out"); 01322 01323 // Before we try to recalculate access paths, try to white-list 01324 // accesses which just trade in on the final step, i.e. accesses 01325 // which don't require [M4] or [B4]. These are by far the most 01326 // common forms of privileged access. 01327 if (UnprivilegedAccess != AS_none) { 01328 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) { 01329 case AR_dependent: 01330 // This is actually an interesting policy decision. We don't 01331 // *have* to delay immediately here: we can do the full access 01332 // calculation in the hope that friendship on some intermediate 01333 // class will make the declaration accessible non-dependently. 01334 // But that's not cheap, and odds are very good (note: assertion 01335 // made without data) that the friend declaration will determine 01336 // access. 01337 return AR_dependent; 01338 01339 case AR_accessible: return AR_accessible; 01340 case AR_inaccessible: break; 01341 } 01342 } 01343 01344 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext(); 01345 01346 // We lower member accesses to base accesses by pretending that the 01347 // member is a base class of its declaring class. 01348 AccessSpecifier FinalAccess; 01349 01350 if (Entity.isMemberAccess()) { 01351 // Determine if the declaration is accessible from EC when named 01352 // in its declaring class. 01353 NamedDecl *Target = Entity.getTargetDecl(); 01354 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 01355 01356 FinalAccess = Target->getAccess(); 01357 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) { 01358 case AR_accessible: 01359 // Target is accessible at EC when named in its declaring class. 01360 // We can now hill-climb and simply check whether the declaring 01361 // class is accessible as a base of the naming class. This is 01362 // equivalent to checking the access of a notional public 01363 // member with no instance context. 01364 FinalAccess = AS_public; 01365 Entity.suppressInstanceContext(); 01366 break; 01367 case AR_inaccessible: break; 01368 case AR_dependent: return AR_dependent; // see above 01369 } 01370 01371 if (DeclaringClass == NamingClass) 01372 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible); 01373 } else { 01374 FinalAccess = AS_public; 01375 } 01376 01377 assert(Entity.getDeclaringClass() != NamingClass); 01378 01379 // Append the declaration's access if applicable. 01380 CXXBasePaths Paths; 01381 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths); 01382 if (!Path) 01383 return AR_dependent; 01384 01385 assert(Path->Access <= UnprivilegedAccess && 01386 "access along best path worse than direct?"); 01387 if (Path->Access == AS_public) 01388 return AR_accessible; 01389 return AR_inaccessible; 01390 } 01391 01392 static void DelayDependentAccess(Sema &S, 01393 const EffectiveContext &EC, 01394 SourceLocation Loc, 01395 const AccessTarget &Entity) { 01396 assert(EC.isDependent() && "delaying non-dependent access"); 01397 DeclContext *DC = EC.getInnerContext(); 01398 assert(DC->isDependentContext() && "delaying non-dependent access"); 01399 DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access, 01400 Loc, 01401 Entity.isMemberAccess(), 01402 Entity.getAccess(), 01403 Entity.getTargetDecl(), 01404 Entity.getNamingClass(), 01405 Entity.getBaseObjectType(), 01406 Entity.getDiag()); 01407 } 01408 01409 /// Checks access to an entity from the given effective context. 01410 static AccessResult CheckEffectiveAccess(Sema &S, 01411 const EffectiveContext &EC, 01412 SourceLocation Loc, 01413 AccessTarget &Entity) { 01414 assert(Entity.getAccess() != AS_public && "called for public access!"); 01415 01416 switch (IsAccessible(S, EC, Entity)) { 01417 case AR_dependent: 01418 DelayDependentAccess(S, EC, Loc, Entity); 01419 return AR_dependent; 01420 01421 case AR_inaccessible: 01422 if (S.getLangOpts().MSVCCompat && 01423 IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity)) 01424 return AR_accessible; 01425 if (!Entity.isQuiet()) 01426 DiagnoseBadAccess(S, Loc, EC, Entity); 01427 return AR_inaccessible; 01428 01429 case AR_accessible: 01430 return AR_accessible; 01431 } 01432 01433 // silence unnecessary warning 01434 llvm_unreachable("invalid access result"); 01435 } 01436 01437 static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, 01438 AccessTarget &Entity) { 01439 // If the access path is public, it's accessible everywhere. 01440 if (Entity.getAccess() == AS_public) 01441 return Sema::AR_accessible; 01442 01443 // If we're currently parsing a declaration, we may need to delay 01444 // access control checking, because our effective context might be 01445 // different based on what the declaration comes out as. 01446 // 01447 // For example, we might be parsing a declaration with a scope 01448 // specifier, like this: 01449 // A::private_type A::foo() { ... } 01450 // 01451 // Or we might be parsing something that will turn out to be a friend: 01452 // void foo(A::private_type); 01453 // void B::foo(A::private_type); 01454 if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { 01455 S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); 01456 return Sema::AR_delayed; 01457 } 01458 01459 EffectiveContext EC(S.CurContext); 01460 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) { 01461 case AR_accessible: return Sema::AR_accessible; 01462 case AR_inaccessible: return Sema::AR_inaccessible; 01463 case AR_dependent: return Sema::AR_dependent; 01464 } 01465 llvm_unreachable("falling off end"); 01466 } 01467 01468 void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) { 01469 // Access control for names used in the declarations of functions 01470 // and function templates should normally be evaluated in the context 01471 // of the declaration, just in case it's a friend of something. 01472 // However, this does not apply to local extern declarations. 01473 01474 DeclContext *DC = D->getDeclContext(); 01475 if (D->isLocalExternDecl()) { 01476 DC = D->getLexicalDeclContext(); 01477 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) { 01478 DC = FN; 01479 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) { 01480 DC = cast<DeclContext>(TD->getTemplatedDecl()); 01481 } 01482 01483 EffectiveContext EC(DC); 01484 01485 AccessTarget Target(DD.getAccessData()); 01486 01487 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible) 01488 DD.Triggered = true; 01489 } 01490 01491 void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD, 01492 const MultiLevelTemplateArgumentList &TemplateArgs) { 01493 SourceLocation Loc = DD.getAccessLoc(); 01494 AccessSpecifier Access = DD.getAccess(); 01495 01496 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(), 01497 TemplateArgs); 01498 if (!NamingD) return; 01499 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(), 01500 TemplateArgs); 01501 if (!TargetD) return; 01502 01503 if (DD.isAccessToMember()) { 01504 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD); 01505 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD); 01506 QualType BaseObjectType = DD.getAccessBaseObjectType(); 01507 if (!BaseObjectType.isNull()) { 01508 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc, 01509 DeclarationName()); 01510 if (BaseObjectType.isNull()) return; 01511 } 01512 01513 AccessTarget Entity(Context, 01514 AccessTarget::Member, 01515 NamingClass, 01516 DeclAccessPair::make(TargetDecl, Access), 01517 BaseObjectType); 01518 Entity.setDiag(DD.getDiagnostic()); 01519 CheckAccess(*this, Loc, Entity); 01520 } else { 01521 AccessTarget Entity(Context, 01522 AccessTarget::Base, 01523 cast<CXXRecordDecl>(TargetD), 01524 cast<CXXRecordDecl>(NamingD), 01525 Access); 01526 Entity.setDiag(DD.getDiagnostic()); 01527 CheckAccess(*this, Loc, Entity); 01528 } 01529 } 01530 01531 Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, 01532 DeclAccessPair Found) { 01533 if (!getLangOpts().AccessControl || 01534 !E->getNamingClass() || 01535 Found.getAccess() == AS_public) 01536 return AR_accessible; 01537 01538 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 01539 Found, QualType()); 01540 Entity.setDiag(diag::err_access) << E->getSourceRange(); 01541 01542 return CheckAccess(*this, E->getNameLoc(), Entity); 01543 } 01544 01545 /// Perform access-control checking on a previously-unresolved member 01546 /// access which has now been resolved to a member. 01547 Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, 01548 DeclAccessPair Found) { 01549 if (!getLangOpts().AccessControl || 01550 Found.getAccess() == AS_public) 01551 return AR_accessible; 01552 01553 QualType BaseType = E->getBaseType(); 01554 if (E->isArrow()) 01555 BaseType = BaseType->getAs<PointerType>()->getPointeeType(); 01556 01557 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 01558 Found, BaseType); 01559 Entity.setDiag(diag::err_access) << E->getSourceRange(); 01560 01561 return CheckAccess(*this, E->getMemberLoc(), Entity); 01562 } 01563 01564 /// Is the given special member function accessible for the purposes of 01565 /// deciding whether to define a special member function as deleted? 01566 bool Sema::isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl, 01567 AccessSpecifier access, 01568 QualType objectType) { 01569 // Fast path. 01570 if (access == AS_public || !getLangOpts().AccessControl) return true; 01571 01572 AccessTarget entity(Context, AccessTarget::Member, decl->getParent(), 01573 DeclAccessPair::make(decl, access), objectType); 01574 01575 // Suppress diagnostics. 01576 entity.setDiag(PDiag()); 01577 01578 switch (CheckAccess(*this, SourceLocation(), entity)) { 01579 case AR_accessible: return true; 01580 case AR_inaccessible: return false; 01581 case AR_dependent: llvm_unreachable("dependent for =delete computation"); 01582 case AR_delayed: llvm_unreachable("cannot delay =delete computation"); 01583 } 01584 llvm_unreachable("bad access result"); 01585 } 01586 01587 Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, 01588 CXXDestructorDecl *Dtor, 01589 const PartialDiagnostic &PDiag, 01590 QualType ObjectTy) { 01591 if (!getLangOpts().AccessControl) 01592 return AR_accessible; 01593 01594 // There's never a path involved when checking implicit destructor access. 01595 AccessSpecifier Access = Dtor->getAccess(); 01596 if (Access == AS_public) 01597 return AR_accessible; 01598 01599 CXXRecordDecl *NamingClass = Dtor->getParent(); 01600 if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass); 01601 01602 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 01603 DeclAccessPair::make(Dtor, Access), 01604 ObjectTy); 01605 Entity.setDiag(PDiag); // TODO: avoid copy 01606 01607 return CheckAccess(*this, Loc, Entity); 01608 } 01609 01610 /// Checks access to a constructor. 01611 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, 01612 CXXConstructorDecl *Constructor, 01613 const InitializedEntity &Entity, 01614 AccessSpecifier Access, 01615 bool IsCopyBindingRefToTemp) { 01616 if (!getLangOpts().AccessControl || Access == AS_public) 01617 return AR_accessible; 01618 01619 PartialDiagnostic PD(PDiag()); 01620 switch (Entity.getKind()) { 01621 default: 01622 PD = PDiag(IsCopyBindingRefToTemp 01623 ? diag::ext_rvalue_to_reference_access_ctor 01624 : diag::err_access_ctor); 01625 01626 break; 01627 01628 case InitializedEntity::EK_Base: 01629 PD = PDiag(diag::err_access_base_ctor); 01630 PD << Entity.isInheritedVirtualBase() 01631 << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor); 01632 break; 01633 01634 case InitializedEntity::EK_Member: { 01635 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl()); 01636 PD = PDiag(diag::err_access_field_ctor); 01637 PD << Field->getType() << getSpecialMember(Constructor); 01638 break; 01639 } 01640 01641 case InitializedEntity::EK_LambdaCapture: { 01642 StringRef VarName = Entity.getCapturedVarName(); 01643 PD = PDiag(diag::err_access_lambda_capture); 01644 PD << VarName << Entity.getType() << getSpecialMember(Constructor); 01645 break; 01646 } 01647 01648 } 01649 01650 return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD); 01651 } 01652 01653 /// Checks access to a constructor. 01654 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, 01655 CXXConstructorDecl *Constructor, 01656 const InitializedEntity &Entity, 01657 AccessSpecifier Access, 01658 const PartialDiagnostic &PD) { 01659 if (!getLangOpts().AccessControl || 01660 Access == AS_public) 01661 return AR_accessible; 01662 01663 CXXRecordDecl *NamingClass = Constructor->getParent(); 01664 01665 // Initializing a base sub-object is an instance method call on an 01666 // object of the derived class. Otherwise, we have an instance method 01667 // call on an object of the constructed type. 01668 CXXRecordDecl *ObjectClass; 01669 if (Entity.getKind() == InitializedEntity::EK_Base) { 01670 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent(); 01671 } else { 01672 ObjectClass = NamingClass; 01673 } 01674 01675 AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass, 01676 DeclAccessPair::make(Constructor, Access), 01677 Context.getTypeDeclType(ObjectClass)); 01678 AccessEntity.setDiag(PD); 01679 01680 return CheckAccess(*this, UseLoc, AccessEntity); 01681 } 01682 01683 /// Checks access to an overloaded operator new or delete. 01684 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, 01685 SourceRange PlacementRange, 01686 CXXRecordDecl *NamingClass, 01687 DeclAccessPair Found, 01688 bool Diagnose) { 01689 if (!getLangOpts().AccessControl || 01690 !NamingClass || 01691 Found.getAccess() == AS_public) 01692 return AR_accessible; 01693 01694 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 01695 QualType()); 01696 if (Diagnose) 01697 Entity.setDiag(diag::err_access) 01698 << PlacementRange; 01699 01700 return CheckAccess(*this, OpLoc, Entity); 01701 } 01702 01703 /// \brief Checks access to a member. 01704 Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc, 01705 CXXRecordDecl *NamingClass, 01706 DeclAccessPair Found) { 01707 if (!getLangOpts().AccessControl || 01708 !NamingClass || 01709 Found.getAccess() == AS_public) 01710 return AR_accessible; 01711 01712 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 01713 Found, QualType()); 01714 01715 return CheckAccess(*this, UseLoc, Entity); 01716 } 01717 01718 /// Checks access to an overloaded member operator, including 01719 /// conversion operators. 01720 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, 01721 Expr *ObjectExpr, 01722 Expr *ArgExpr, 01723 DeclAccessPair Found) { 01724 if (!getLangOpts().AccessControl || 01725 Found.getAccess() == AS_public) 01726 return AR_accessible; 01727 01728 const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>(); 01729 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl()); 01730 01731 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 01732 ObjectExpr->getType()); 01733 Entity.setDiag(diag::err_access) 01734 << ObjectExpr->getSourceRange() 01735 << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); 01736 01737 return CheckAccess(*this, OpLoc, Entity); 01738 } 01739 01740 /// Checks access to the target of a friend declaration. 01741 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) { 01742 assert(isa<CXXMethodDecl>(target->getAsFunction())); 01743 01744 // Friendship lookup is a redeclaration lookup, so there's never an 01745 // inheritance path modifying access. 01746 AccessSpecifier access = target->getAccess(); 01747 01748 if (!getLangOpts().AccessControl || access == AS_public) 01749 return AR_accessible; 01750 01751 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction()); 01752 assert(method->getQualifier()); 01753 01754 AccessTarget entity(Context, AccessTarget::Member, 01755 cast<CXXRecordDecl>(target->getDeclContext()), 01756 DeclAccessPair::make(target, access), 01757 /*no instance context*/ QualType()); 01758 entity.setDiag(diag::err_access_friend_function) 01759 << method->getQualifierLoc().getSourceRange(); 01760 01761 // We need to bypass delayed-diagnostics because we might be called 01762 // while the ParsingDeclarator is active. 01763 EffectiveContext EC(CurContext); 01764 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) { 01765 case AR_accessible: return Sema::AR_accessible; 01766 case AR_inaccessible: return Sema::AR_inaccessible; 01767 case AR_dependent: return Sema::AR_dependent; 01768 } 01769 llvm_unreachable("falling off end"); 01770 } 01771 01772 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr, 01773 DeclAccessPair Found) { 01774 if (!getLangOpts().AccessControl || 01775 Found.getAccess() == AS_none || 01776 Found.getAccess() == AS_public) 01777 return AR_accessible; 01778 01779 OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression; 01780 CXXRecordDecl *NamingClass = Ovl->getNamingClass(); 01781 01782 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 01783 /*no instance context*/ QualType()); 01784 Entity.setDiag(diag::err_access) 01785 << Ovl->getSourceRange(); 01786 01787 return CheckAccess(*this, Ovl->getNameLoc(), Entity); 01788 } 01789 01790 /// Checks access for a hierarchy conversion. 01791 /// 01792 /// \param ForceCheck true if this check should be performed even if access 01793 /// control is disabled; some things rely on this for semantics 01794 /// \param ForceUnprivileged true if this check should proceed as if the 01795 /// context had no special privileges 01796 Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, 01797 QualType Base, 01798 QualType Derived, 01799 const CXXBasePath &Path, 01800 unsigned DiagID, 01801 bool ForceCheck, 01802 bool ForceUnprivileged) { 01803 if (!ForceCheck && !getLangOpts().AccessControl) 01804 return AR_accessible; 01805 01806 if (Path.Access == AS_public) 01807 return AR_accessible; 01808 01809 CXXRecordDecl *BaseD, *DerivedD; 01810 BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl()); 01811 DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl()); 01812 01813 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD, 01814 Path.Access); 01815 if (DiagID) 01816 Entity.setDiag(DiagID) << Derived << Base; 01817 01818 if (ForceUnprivileged) { 01819 switch (CheckEffectiveAccess(*this, EffectiveContext(), 01820 AccessLoc, Entity)) { 01821 case ::AR_accessible: return Sema::AR_accessible; 01822 case ::AR_inaccessible: return Sema::AR_inaccessible; 01823 case ::AR_dependent: return Sema::AR_dependent; 01824 } 01825 llvm_unreachable("unexpected result from CheckEffectiveAccess"); 01826 } 01827 return CheckAccess(*this, AccessLoc, Entity); 01828 } 01829 01830 /// Checks access to all the declarations in the given result set. 01831 void Sema::CheckLookupAccess(const LookupResult &R) { 01832 assert(getLangOpts().AccessControl 01833 && "performing access check without access control"); 01834 assert(R.getNamingClass() && "performing access check without naming class"); 01835 01836 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { 01837 if (I.getAccess() != AS_public) { 01838 AccessTarget Entity(Context, AccessedEntity::Member, 01839 R.getNamingClass(), I.getPair(), 01840 R.getBaseObjectType()); 01841 Entity.setDiag(diag::err_access); 01842 CheckAccess(*this, R.getNameLoc(), Entity); 01843 } 01844 } 01845 } 01846 01847 /// Checks access to Decl from the given class. The check will take access 01848 /// specifiers into account, but no member access expressions and such. 01849 /// 01850 /// \param Decl the declaration to check if it can be accessed 01851 /// \param Ctx the class/context from which to start the search 01852 /// \return true if the Decl is accessible from the Class, false otherwise. 01853 bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) { 01854 if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) { 01855 if (!Decl->isCXXClassMember()) 01856 return true; 01857 01858 QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal(); 01859 AccessTarget Entity(Context, AccessedEntity::Member, Class, 01860 DeclAccessPair::make(Decl, Decl->getAccess()), 01861 qType); 01862 if (Entity.getAccess() == AS_public) 01863 return true; 01864 01865 EffectiveContext EC(CurContext); 01866 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible; 01867 } 01868 01869 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) { 01870 // @public and @package ivars are always accessible. 01871 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public || 01872 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package) 01873 return true; 01874 01875 // If we are inside a class or category implementation, determine the 01876 // interface we're in. 01877 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr; 01878 if (ObjCMethodDecl *MD = getCurMethodDecl()) 01879 ClassOfMethodDecl = MD->getClassInterface(); 01880 else if (FunctionDecl *FD = getCurFunctionDecl()) { 01881 if (ObjCImplDecl *Impl 01882 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) { 01883 if (ObjCImplementationDecl *IMPD 01884 = dyn_cast<ObjCImplementationDecl>(Impl)) 01885 ClassOfMethodDecl = IMPD->getClassInterface(); 01886 else if (ObjCCategoryImplDecl* CatImplClass 01887 = dyn_cast<ObjCCategoryImplDecl>(Impl)) 01888 ClassOfMethodDecl = CatImplClass->getClassInterface(); 01889 } 01890 } 01891 01892 // If we're not in an interface, this ivar is inaccessible. 01893 if (!ClassOfMethodDecl) 01894 return false; 01895 01896 // If we're inside the same interface that owns the ivar, we're fine. 01897 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface())) 01898 return true; 01899 01900 // If the ivar is private, it's inaccessible. 01901 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private) 01902 return false; 01903 01904 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl); 01905 } 01906 01907 return true; 01908 }