SemaAccess.cpp revision 17015eff2b3166e445377b15913474b472775e7c
1//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file provides Sema routines for C++ access control semantics. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Sema/SemaInternal.h" 15#include "clang/Sema/DelayedDiagnostic.h" 16#include "clang/Sema/Initialization.h" 17#include "clang/Sema/Lookup.h" 18#include "clang/AST/ASTContext.h" 19#include "clang/AST/CXXInheritance.h" 20#include "clang/AST/DeclCXX.h" 21#include "clang/AST/DeclFriend.h" 22#include "clang/AST/DependentDiagnostic.h" 23#include "clang/AST/ExprCXX.h" 24 25using namespace clang; 26using namespace sema; 27 28/// A copy of Sema's enum without AR_delayed. 29enum AccessResult { 30 AR_accessible, 31 AR_inaccessible, 32 AR_dependent 33}; 34 35/// SetMemberAccessSpecifier - Set the access specifier of a member. 36/// Returns true on error (when the previous member decl access specifier 37/// is different from the new member decl access specifier). 38bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, 39 NamedDecl *PrevMemberDecl, 40 AccessSpecifier LexicalAS) { 41 if (!PrevMemberDecl) { 42 // Use the lexical access specifier. 43 MemberDecl->setAccess(LexicalAS); 44 return false; 45 } 46 47 // C++ [class.access.spec]p3: When a member is redeclared its access 48 // specifier must be same as its initial declaration. 49 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) { 50 Diag(MemberDecl->getLocation(), 51 diag::err_class_redeclared_with_different_access) 52 << MemberDecl << LexicalAS; 53 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration) 54 << PrevMemberDecl << PrevMemberDecl->getAccess(); 55 56 MemberDecl->setAccess(LexicalAS); 57 return true; 58 } 59 60 MemberDecl->setAccess(PrevMemberDecl->getAccess()); 61 return false; 62} 63 64static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) { 65 DeclContext *DC = D->getDeclContext(); 66 67 // This can only happen at top: enum decls only "publish" their 68 // immediate members. 69 if (isa<EnumDecl>(DC)) 70 DC = cast<EnumDecl>(DC)->getDeclContext(); 71 72 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC); 73 while (DeclaringClass->isAnonymousStructOrUnion()) 74 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext()); 75 return DeclaringClass; 76} 77 78namespace { 79struct EffectiveContext { 80 EffectiveContext() : Inner(0), Dependent(false) {} 81 82 explicit EffectiveContext(DeclContext *DC) 83 : Inner(DC), 84 Dependent(DC->isDependentContext()) { 85 86 // C++ [class.access.nest]p1: 87 // A nested class is a member and as such has the same access 88 // rights as any other member. 89 // C++ [class.access]p2: 90 // A member of a class can also access all the names to which 91 // the class has access. A local class of a member function 92 // may access the same names that the member function itself 93 // may access. 94 // This almost implies that the privileges of nesting are transitive. 95 // Technically it says nothing about the local classes of non-member 96 // functions (which can gain privileges through friendship), but we 97 // take that as an oversight. 98 while (true) { 99 if (isa<CXXRecordDecl>(DC)) { 100 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl(); 101 Records.push_back(Record); 102 DC = Record->getDeclContext(); 103 } else if (isa<FunctionDecl>(DC)) { 104 FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl(); 105 Functions.push_back(Function); 106 107 if (Function->getFriendObjectKind()) 108 DC = Function->getLexicalDeclContext(); 109 else 110 DC = Function->getDeclContext(); 111 } else if (DC->isFileContext()) { 112 break; 113 } else { 114 DC = DC->getParent(); 115 } 116 } 117 } 118 119 bool isDependent() const { return Dependent; } 120 121 bool includesClass(const CXXRecordDecl *R) const { 122 R = R->getCanonicalDecl(); 123 return std::find(Records.begin(), Records.end(), R) 124 != Records.end(); 125 } 126 127 /// Retrieves the innermost "useful" context. Can be null if we're 128 /// doing access-control without privileges. 129 DeclContext *getInnerContext() const { 130 return Inner; 131 } 132 133 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator; 134 135 DeclContext *Inner; 136 SmallVector<FunctionDecl*, 4> Functions; 137 SmallVector<CXXRecordDecl*, 4> Records; 138 bool Dependent; 139}; 140 141/// Like sema::AccessedEntity, but kindly lets us scribble all over 142/// it. 143struct AccessTarget : public AccessedEntity { 144 AccessTarget(const AccessedEntity &Entity) 145 : AccessedEntity(Entity) { 146 initialize(); 147 } 148 149 AccessTarget(ASTContext &Context, 150 MemberNonce _, 151 CXXRecordDecl *NamingClass, 152 DeclAccessPair FoundDecl, 153 QualType BaseObjectType) 154 : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) { 155 initialize(); 156 } 157 158 AccessTarget(ASTContext &Context, 159 BaseNonce _, 160 CXXRecordDecl *BaseClass, 161 CXXRecordDecl *DerivedClass, 162 AccessSpecifier Access) 163 : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) { 164 initialize(); 165 } 166 167 bool hasInstanceContext() const { 168 return HasInstanceContext; 169 } 170 171 class SavedInstanceContext { 172 public: 173 ~SavedInstanceContext() { 174 Target.HasInstanceContext = Has; 175 } 176 177 private: 178 friend struct AccessTarget; 179 explicit SavedInstanceContext(AccessTarget &Target) 180 : Target(Target), Has(Target.HasInstanceContext) {} 181 AccessTarget &Target; 182 bool Has; 183 }; 184 185 SavedInstanceContext saveInstanceContext() { 186 return SavedInstanceContext(*this); 187 } 188 189 void suppressInstanceContext() { 190 HasInstanceContext = false; 191 } 192 193 const CXXRecordDecl *resolveInstanceContext(Sema &S) const { 194 assert(HasInstanceContext); 195 if (CalculatedInstanceContext) 196 return InstanceContext; 197 198 CalculatedInstanceContext = true; 199 DeclContext *IC = S.computeDeclContext(getBaseObjectType()); 200 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0); 201 return InstanceContext; 202 } 203 204 const CXXRecordDecl *getDeclaringClass() const { 205 return DeclaringClass; 206 } 207 208private: 209 void initialize() { 210 HasInstanceContext = (isMemberAccess() && 211 !getBaseObjectType().isNull() && 212 getTargetDecl()->isCXXInstanceMember()); 213 CalculatedInstanceContext = false; 214 InstanceContext = 0; 215 216 if (isMemberAccess()) 217 DeclaringClass = FindDeclaringClass(getTargetDecl()); 218 else 219 DeclaringClass = getBaseClass(); 220 DeclaringClass = DeclaringClass->getCanonicalDecl(); 221 } 222 223 bool HasInstanceContext : 1; 224 mutable bool CalculatedInstanceContext : 1; 225 mutable const CXXRecordDecl *InstanceContext; 226 const CXXRecordDecl *DeclaringClass; 227}; 228 229} 230 231/// Checks whether one class might instantiate to the other. 232static bool MightInstantiateTo(const CXXRecordDecl *From, 233 const CXXRecordDecl *To) { 234 // Declaration names are always preserved by instantiation. 235 if (From->getDeclName() != To->getDeclName()) 236 return false; 237 238 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext(); 239 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext(); 240 if (FromDC == ToDC) return true; 241 if (FromDC->isFileContext() || ToDC->isFileContext()) return false; 242 243 // Be conservative. 244 return true; 245} 246 247/// Checks whether one class is derived from another, inclusively. 248/// Properly indicates when it couldn't be determined due to 249/// dependence. 250/// 251/// This should probably be donated to AST or at least Sema. 252static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, 253 const CXXRecordDecl *Target) { 254 assert(Derived->getCanonicalDecl() == Derived); 255 assert(Target->getCanonicalDecl() == Target); 256 257 if (Derived == Target) return AR_accessible; 258 259 bool CheckDependent = Derived->isDependentContext(); 260 if (CheckDependent && MightInstantiateTo(Derived, Target)) 261 return AR_dependent; 262 263 AccessResult OnFailure = AR_inaccessible; 264 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack 265 266 while (true) { 267 for (CXXRecordDecl::base_class_const_iterator 268 I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) { 269 270 const CXXRecordDecl *RD; 271 272 QualType T = I->getType(); 273 if (const RecordType *RT = T->getAs<RecordType>()) { 274 RD = cast<CXXRecordDecl>(RT->getDecl()); 275 } else if (const InjectedClassNameType *IT 276 = T->getAs<InjectedClassNameType>()) { 277 RD = IT->getDecl(); 278 } else { 279 assert(T->isDependentType() && "non-dependent base wasn't a record?"); 280 OnFailure = AR_dependent; 281 continue; 282 } 283 284 RD = RD->getCanonicalDecl(); 285 if (RD == Target) return AR_accessible; 286 if (CheckDependent && MightInstantiateTo(RD, Target)) 287 OnFailure = AR_dependent; 288 289 Queue.push_back(RD); 290 } 291 292 if (Queue.empty()) break; 293 294 Derived = Queue.back(); 295 Queue.pop_back(); 296 } 297 298 return OnFailure; 299} 300 301 302static bool MightInstantiateTo(Sema &S, DeclContext *Context, 303 DeclContext *Friend) { 304 if (Friend == Context) 305 return true; 306 307 assert(!Friend->isDependentContext() && 308 "can't handle friends with dependent contexts here"); 309 310 if (!Context->isDependentContext()) 311 return false; 312 313 if (Friend->isFileContext()) 314 return false; 315 316 // TODO: this is very conservative 317 return true; 318} 319 320// Asks whether the type in 'context' can ever instantiate to the type 321// in 'friend'. 322static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) { 323 if (Friend == Context) 324 return true; 325 326 if (!Friend->isDependentType() && !Context->isDependentType()) 327 return false; 328 329 // TODO: this is very conservative. 330 return true; 331} 332 333static bool MightInstantiateTo(Sema &S, 334 FunctionDecl *Context, 335 FunctionDecl *Friend) { 336 if (Context->getDeclName() != Friend->getDeclName()) 337 return false; 338 339 if (!MightInstantiateTo(S, 340 Context->getDeclContext(), 341 Friend->getDeclContext())) 342 return false; 343 344 CanQual<FunctionProtoType> FriendTy 345 = S.Context.getCanonicalType(Friend->getType()) 346 ->getAs<FunctionProtoType>(); 347 CanQual<FunctionProtoType> ContextTy 348 = S.Context.getCanonicalType(Context->getType()) 349 ->getAs<FunctionProtoType>(); 350 351 // There isn't any way that I know of to add qualifiers 352 // during instantiation. 353 if (FriendTy.getQualifiers() != ContextTy.getQualifiers()) 354 return false; 355 356 if (FriendTy->getNumArgs() != ContextTy->getNumArgs()) 357 return false; 358 359 if (!MightInstantiateTo(S, 360 ContextTy->getResultType(), 361 FriendTy->getResultType())) 362 return false; 363 364 for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I) 365 if (!MightInstantiateTo(S, 366 ContextTy->getArgType(I), 367 FriendTy->getArgType(I))) 368 return false; 369 370 return true; 371} 372 373static bool MightInstantiateTo(Sema &S, 374 FunctionTemplateDecl *Context, 375 FunctionTemplateDecl *Friend) { 376 return MightInstantiateTo(S, 377 Context->getTemplatedDecl(), 378 Friend->getTemplatedDecl()); 379} 380 381static AccessResult MatchesFriend(Sema &S, 382 const EffectiveContext &EC, 383 const CXXRecordDecl *Friend) { 384 if (EC.includesClass(Friend)) 385 return AR_accessible; 386 387 if (EC.isDependent()) { 388 CanQualType FriendTy 389 = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend)); 390 391 for (EffectiveContext::record_iterator 392 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 393 CanQualType ContextTy 394 = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I)); 395 if (MightInstantiateTo(S, ContextTy, FriendTy)) 396 return AR_dependent; 397 } 398 } 399 400 return AR_inaccessible; 401} 402 403static AccessResult MatchesFriend(Sema &S, 404 const EffectiveContext &EC, 405 CanQualType Friend) { 406 if (const RecordType *RT = Friend->getAs<RecordType>()) 407 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl())); 408 409 // TODO: we can do better than this 410 if (Friend->isDependentType()) 411 return AR_dependent; 412 413 return AR_inaccessible; 414} 415 416/// Determines whether the given friend class template matches 417/// anything in the effective context. 418static AccessResult MatchesFriend(Sema &S, 419 const EffectiveContext &EC, 420 ClassTemplateDecl *Friend) { 421 AccessResult OnFailure = AR_inaccessible; 422 423 // Check whether the friend is the template of a class in the 424 // context chain. 425 for (SmallVectorImpl<CXXRecordDecl*>::const_iterator 426 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 427 CXXRecordDecl *Record = *I; 428 429 // Figure out whether the current class has a template: 430 ClassTemplateDecl *CTD; 431 432 // A specialization of the template... 433 if (isa<ClassTemplateSpecializationDecl>(Record)) { 434 CTD = cast<ClassTemplateSpecializationDecl>(Record) 435 ->getSpecializedTemplate(); 436 437 // ... or the template pattern itself. 438 } else { 439 CTD = Record->getDescribedClassTemplate(); 440 if (!CTD) continue; 441 } 442 443 // It's a match. 444 if (Friend == CTD->getCanonicalDecl()) 445 return AR_accessible; 446 447 // If the context isn't dependent, it can't be a dependent match. 448 if (!EC.isDependent()) 449 continue; 450 451 // If the template names don't match, it can't be a dependent 452 // match. 453 if (CTD->getDeclName() != Friend->getDeclName()) 454 continue; 455 456 // If the class's context can't instantiate to the friend's 457 // context, it can't be a dependent match. 458 if (!MightInstantiateTo(S, CTD->getDeclContext(), 459 Friend->getDeclContext())) 460 continue; 461 462 // Otherwise, it's a dependent match. 463 OnFailure = AR_dependent; 464 } 465 466 return OnFailure; 467} 468 469/// Determines whether the given friend function matches anything in 470/// the effective context. 471static AccessResult MatchesFriend(Sema &S, 472 const EffectiveContext &EC, 473 FunctionDecl *Friend) { 474 AccessResult OnFailure = AR_inaccessible; 475 476 for (SmallVectorImpl<FunctionDecl*>::const_iterator 477 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 478 if (Friend == *I) 479 return AR_accessible; 480 481 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend)) 482 OnFailure = AR_dependent; 483 } 484 485 return OnFailure; 486} 487 488/// Determines whether the given friend function template matches 489/// anything in the effective context. 490static AccessResult MatchesFriend(Sema &S, 491 const EffectiveContext &EC, 492 FunctionTemplateDecl *Friend) { 493 if (EC.Functions.empty()) return AR_inaccessible; 494 495 AccessResult OnFailure = AR_inaccessible; 496 497 for (SmallVectorImpl<FunctionDecl*>::const_iterator 498 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 499 500 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate(); 501 if (!FTD) 502 FTD = (*I)->getDescribedFunctionTemplate(); 503 if (!FTD) 504 continue; 505 506 FTD = FTD->getCanonicalDecl(); 507 508 if (Friend == FTD) 509 return AR_accessible; 510 511 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend)) 512 OnFailure = AR_dependent; 513 } 514 515 return OnFailure; 516} 517 518/// Determines whether the given friend declaration matches anything 519/// in the effective context. 520static AccessResult MatchesFriend(Sema &S, 521 const EffectiveContext &EC, 522 FriendDecl *FriendD) { 523 // Whitelist accesses if there's an invalid or unsupported friend 524 // declaration. 525 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend()) 526 return AR_accessible; 527 528 if (TypeSourceInfo *T = FriendD->getFriendType()) 529 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified()); 530 531 NamedDecl *Friend 532 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl()); 533 534 // FIXME: declarations with dependent or templated scope. 535 536 if (isa<ClassTemplateDecl>(Friend)) 537 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend)); 538 539 if (isa<FunctionTemplateDecl>(Friend)) 540 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend)); 541 542 if (isa<CXXRecordDecl>(Friend)) 543 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend)); 544 545 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind"); 546 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend)); 547} 548 549static AccessResult GetFriendKind(Sema &S, 550 const EffectiveContext &EC, 551 const CXXRecordDecl *Class) { 552 AccessResult OnFailure = AR_inaccessible; 553 554 // Okay, check friends. 555 for (CXXRecordDecl::friend_iterator I = Class->friend_begin(), 556 E = Class->friend_end(); I != E; ++I) { 557 FriendDecl *Friend = *I; 558 559 switch (MatchesFriend(S, EC, Friend)) { 560 case AR_accessible: 561 return AR_accessible; 562 563 case AR_inaccessible: 564 continue; 565 566 case AR_dependent: 567 OnFailure = AR_dependent; 568 break; 569 } 570 } 571 572 // That's it, give up. 573 return OnFailure; 574} 575 576namespace { 577 578/// A helper class for checking for a friend which will grant access 579/// to a protected instance member. 580struct ProtectedFriendContext { 581 Sema &S; 582 const EffectiveContext &EC; 583 const CXXRecordDecl *NamingClass; 584 bool CheckDependent; 585 bool EverDependent; 586 587 /// The path down to the current base class. 588 SmallVector<const CXXRecordDecl*, 20> CurPath; 589 590 ProtectedFriendContext(Sema &S, const EffectiveContext &EC, 591 const CXXRecordDecl *InstanceContext, 592 const CXXRecordDecl *NamingClass) 593 : S(S), EC(EC), NamingClass(NamingClass), 594 CheckDependent(InstanceContext->isDependentContext() || 595 NamingClass->isDependentContext()), 596 EverDependent(false) {} 597 598 /// Check classes in the current path for friendship, starting at 599 /// the given index. 600 bool checkFriendshipAlongPath(unsigned I) { 601 assert(I < CurPath.size()); 602 for (unsigned E = CurPath.size(); I != E; ++I) { 603 switch (GetFriendKind(S, EC, CurPath[I])) { 604 case AR_accessible: return true; 605 case AR_inaccessible: continue; 606 case AR_dependent: EverDependent = true; continue; 607 } 608 } 609 return false; 610 } 611 612 /// Perform a search starting at the given class. 613 /// 614 /// PrivateDepth is the index of the last (least derived) class 615 /// along the current path such that a notional public member of 616 /// the final class in the path would have access in that class. 617 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) { 618 // If we ever reach the naming class, check the current path for 619 // friendship. We can also stop recursing because we obviously 620 // won't find the naming class there again. 621 if (Cur == NamingClass) 622 return checkFriendshipAlongPath(PrivateDepth); 623 624 if (CheckDependent && MightInstantiateTo(Cur, NamingClass)) 625 EverDependent = true; 626 627 // Recurse into the base classes. 628 for (CXXRecordDecl::base_class_const_iterator 629 I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) { 630 631 // If this is private inheritance, then a public member of the 632 // base will not have any access in classes derived from Cur. 633 unsigned BasePrivateDepth = PrivateDepth; 634 if (I->getAccessSpecifier() == AS_private) 635 BasePrivateDepth = CurPath.size() - 1; 636 637 const CXXRecordDecl *RD; 638 639 QualType T = I->getType(); 640 if (const RecordType *RT = T->getAs<RecordType>()) { 641 RD = cast<CXXRecordDecl>(RT->getDecl()); 642 } else if (const InjectedClassNameType *IT 643 = T->getAs<InjectedClassNameType>()) { 644 RD = IT->getDecl(); 645 } else { 646 assert(T->isDependentType() && "non-dependent base wasn't a record?"); 647 EverDependent = true; 648 continue; 649 } 650 651 // Recurse. We don't need to clean up if this returns true. 652 CurPath.push_back(RD); 653 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth)) 654 return true; 655 CurPath.pop_back(); 656 } 657 658 return false; 659 } 660 661 bool findFriendship(const CXXRecordDecl *Cur) { 662 assert(CurPath.empty()); 663 CurPath.push_back(Cur); 664 return findFriendship(Cur, 0); 665 } 666}; 667} 668 669/// Search for a class P that EC is a friend of, under the constraint 670/// InstanceContext <= P <= NamingClass 671/// and with the additional restriction that a protected member of 672/// NamingClass would have some natural access in P. 673/// 674/// That second condition isn't actually quite right: the condition in 675/// the standard is whether the target would have some natural access 676/// in P. The difference is that the target might be more accessible 677/// along some path not passing through NamingClass. Allowing that 678/// introduces two problems: 679/// - It breaks encapsulation because you can suddenly access a 680/// forbidden base class's members by subclassing it elsewhere. 681/// - It makes access substantially harder to compute because it 682/// breaks the hill-climbing algorithm: knowing that the target is 683/// accessible in some base class would no longer let you change 684/// the question solely to whether the base class is accessible, 685/// because the original target might have been more accessible 686/// because of crazy subclassing. 687/// So we don't implement that. 688static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, 689 const CXXRecordDecl *InstanceContext, 690 const CXXRecordDecl *NamingClass) { 691 assert(InstanceContext->getCanonicalDecl() == InstanceContext); 692 assert(NamingClass->getCanonicalDecl() == NamingClass); 693 694 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass); 695 if (PRC.findFriendship(InstanceContext)) return AR_accessible; 696 if (PRC.EverDependent) return AR_dependent; 697 return AR_inaccessible; 698} 699 700static AccessResult HasAccess(Sema &S, 701 const EffectiveContext &EC, 702 const CXXRecordDecl *NamingClass, 703 AccessSpecifier Access, 704 const AccessTarget &Target) { 705 assert(NamingClass->getCanonicalDecl() == NamingClass && 706 "declaration should be canonicalized before being passed here"); 707 708 if (Access == AS_public) return AR_accessible; 709 assert(Access == AS_private || Access == AS_protected); 710 711 AccessResult OnFailure = AR_inaccessible; 712 713 for (EffectiveContext::record_iterator 714 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 715 // All the declarations in EC have been canonicalized, so pointer 716 // equality from this point on will work fine. 717 const CXXRecordDecl *ECRecord = *I; 718 719 // [B2] and [M2] 720 if (Access == AS_private) { 721 if (ECRecord == NamingClass) 722 return AR_accessible; 723 724 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass)) 725 OnFailure = AR_dependent; 726 727 // [B3] and [M3] 728 } else { 729 assert(Access == AS_protected); 730 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) { 731 case AR_accessible: break; 732 case AR_inaccessible: continue; 733 case AR_dependent: OnFailure = AR_dependent; continue; 734 } 735 736 if (!Target.hasInstanceContext()) 737 return AR_accessible; 738 739 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 740 if (!InstanceContext) { 741 OnFailure = AR_dependent; 742 continue; 743 } 744 745 // C++ [class.protected]p1: 746 // An additional access check beyond those described earlier in 747 // [class.access] is applied when a non-static data member or 748 // non-static member function is a protected member of its naming 749 // class. As described earlier, access to a protected member is 750 // granted because the reference occurs in a friend or member of 751 // some class C. If the access is to form a pointer to member, 752 // the nested-name-specifier shall name C or a class derived from 753 // C. All other accesses involve a (possibly implicit) object 754 // expression. In this case, the class of the object expression 755 // shall be C or a class derived from C. 756 // 757 // We interpret this as a restriction on [M3]. Most of the 758 // conditions are encoded by not having any instance context. 759 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) { 760 case AR_accessible: return AR_accessible; 761 case AR_inaccessible: continue; 762 case AR_dependent: OnFailure = AR_dependent; continue; 763 } 764 } 765 } 766 767 // [M3] and [B3] say that, if the target is protected in N, we grant 768 // access if the access occurs in a friend or member of some class P 769 // that's a subclass of N and where the target has some natural 770 // access in P. The 'member' aspect is easy to handle because P 771 // would necessarily be one of the effective-context records, and we 772 // address that above. The 'friend' aspect is completely ridiculous 773 // to implement because there are no restrictions at all on P 774 // *unless* the [class.protected] restriction applies. If it does, 775 // however, we should ignore whether the naming class is a friend, 776 // and instead rely on whether any potential P is a friend. 777 if (Access == AS_protected && Target.hasInstanceContext()) { 778 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 779 if (!InstanceContext) return AR_dependent; 780 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) { 781 case AR_accessible: return AR_accessible; 782 case AR_inaccessible: return OnFailure; 783 case AR_dependent: return AR_dependent; 784 } 785 llvm_unreachable("impossible friendship kind"); 786 } 787 788 switch (GetFriendKind(S, EC, NamingClass)) { 789 case AR_accessible: return AR_accessible; 790 case AR_inaccessible: return OnFailure; 791 case AR_dependent: return AR_dependent; 792 } 793 794 // Silence bogus warnings 795 llvm_unreachable("impossible friendship kind"); 796 return OnFailure; 797} 798 799/// Finds the best path from the naming class to the declaring class, 800/// taking friend declarations into account. 801/// 802/// C++0x [class.access.base]p5: 803/// A member m is accessible at the point R when named in class N if 804/// [M1] m as a member of N is public, or 805/// [M2] m as a member of N is private, and R occurs in a member or 806/// friend of class N, or 807/// [M3] m as a member of N is protected, and R occurs in a member or 808/// friend of class N, or in a member or friend of a class P 809/// derived from N, where m as a member of P is public, private, 810/// or protected, or 811/// [M4] there exists a base class B of N that is accessible at R, and 812/// m is accessible at R when named in class B. 813/// 814/// C++0x [class.access.base]p4: 815/// A base class B of N is accessible at R, if 816/// [B1] an invented public member of B would be a public member of N, or 817/// [B2] R occurs in a member or friend of class N, and an invented public 818/// member of B would be a private or protected member of N, or 819/// [B3] R occurs in a member or friend of a class P derived from N, and an 820/// invented public member of B would be a private or protected member 821/// of P, or 822/// [B4] there exists a class S such that B is a base class of S accessible 823/// at R and S is a base class of N accessible at R. 824/// 825/// Along a single inheritance path we can restate both of these 826/// iteratively: 827/// 828/// First, we note that M1-4 are equivalent to B1-4 if the member is 829/// treated as a notional base of its declaring class with inheritance 830/// access equivalent to the member's access. Therefore we need only 831/// ask whether a class B is accessible from a class N in context R. 832/// 833/// Let B_1 .. B_n be the inheritance path in question (i.e. where 834/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of 835/// B_i). For i in 1..n, we will calculate ACAB(i), the access to the 836/// closest accessible base in the path: 837/// Access(a, b) = (* access on the base specifier from a to b *) 838/// Merge(a, forbidden) = forbidden 839/// Merge(a, private) = forbidden 840/// Merge(a, b) = min(a,b) 841/// Accessible(c, forbidden) = false 842/// Accessible(c, private) = (R is c) || IsFriend(c, R) 843/// Accessible(c, protected) = (R derived from c) || IsFriend(c, R) 844/// Accessible(c, public) = true 845/// ACAB(n) = public 846/// ACAB(i) = 847/// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in 848/// if Accessible(B_i, AccessToBase) then public else AccessToBase 849/// 850/// B is an accessible base of N at R iff ACAB(1) = public. 851/// 852/// \param FinalAccess the access of the "final step", or AS_public if 853/// there is no final step. 854/// \return null if friendship is dependent 855static CXXBasePath *FindBestPath(Sema &S, 856 const EffectiveContext &EC, 857 AccessTarget &Target, 858 AccessSpecifier FinalAccess, 859 CXXBasePaths &Paths) { 860 // Derive the paths to the desired base. 861 const CXXRecordDecl *Derived = Target.getNamingClass(); 862 const CXXRecordDecl *Base = Target.getDeclaringClass(); 863 864 // FIXME: fail correctly when there are dependent paths. 865 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base), 866 Paths); 867 assert(isDerived && "derived class not actually derived from base"); 868 (void) isDerived; 869 870 CXXBasePath *BestPath = 0; 871 872 assert(FinalAccess != AS_none && "forbidden access after declaring class"); 873 874 bool AnyDependent = false; 875 876 // Derive the friend-modified access along each path. 877 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end(); 878 PI != PE; ++PI) { 879 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext(); 880 881 // Walk through the path backwards. 882 AccessSpecifier PathAccess = FinalAccess; 883 CXXBasePath::iterator I = PI->end(), E = PI->begin(); 884 while (I != E) { 885 --I; 886 887 assert(PathAccess != AS_none); 888 889 // If the declaration is a private member of a base class, there 890 // is no level of friendship in derived classes that can make it 891 // accessible. 892 if (PathAccess == AS_private) { 893 PathAccess = AS_none; 894 break; 895 } 896 897 const CXXRecordDecl *NC = I->Class->getCanonicalDecl(); 898 899 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier(); 900 PathAccess = std::max(PathAccess, BaseAccess); 901 902 switch (HasAccess(S, EC, NC, PathAccess, Target)) { 903 case AR_inaccessible: break; 904 case AR_accessible: 905 PathAccess = AS_public; 906 907 // Future tests are not against members and so do not have 908 // instance context. 909 Target.suppressInstanceContext(); 910 break; 911 case AR_dependent: 912 AnyDependent = true; 913 goto Next; 914 } 915 } 916 917 // Note that we modify the path's Access field to the 918 // friend-modified access. 919 if (BestPath == 0 || PathAccess < BestPath->Access) { 920 BestPath = &*PI; 921 BestPath->Access = PathAccess; 922 923 // Short-circuit if we found a public path. 924 if (BestPath->Access == AS_public) 925 return BestPath; 926 } 927 928 Next: ; 929 } 930 931 assert((!BestPath || BestPath->Access != AS_public) && 932 "fell out of loop with public path"); 933 934 // We didn't find a public path, but at least one path was subject 935 // to dependent friendship, so delay the check. 936 if (AnyDependent) 937 return 0; 938 939 return BestPath; 940} 941 942/// Given that an entity has protected natural access, check whether 943/// access might be denied because of the protected member access 944/// restriction. 945/// 946/// \return true if a note was emitted 947static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, 948 AccessTarget &Target) { 949 // Only applies to instance accesses. 950 if (!Target.hasInstanceContext()) 951 return false; 952 assert(Target.isMemberAccess()); 953 NamedDecl *D = Target.getTargetDecl(); 954 955 const CXXRecordDecl *DeclaringClass = Target.getDeclaringClass(); 956 DeclaringClass = DeclaringClass->getCanonicalDecl(); 957 958 for (EffectiveContext::record_iterator 959 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 960 const CXXRecordDecl *ECRecord = *I; 961 switch (IsDerivedFromInclusive(ECRecord, DeclaringClass)) { 962 case AR_accessible: break; 963 case AR_inaccessible: continue; 964 case AR_dependent: continue; 965 } 966 967 // The effective context is a subclass of the declaring class. 968 // If that class isn't a superclass of the instance context, 969 // then the [class.protected] restriction applies. 970 971 // To get this exactly right, this might need to be checked more 972 // holistically; it's not necessarily the case that gaining 973 // access here would grant us access overall. 974 975 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 976 assert(InstanceContext && "diagnosing dependent access"); 977 978 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) { 979 case AR_accessible: continue; 980 case AR_dependent: continue; 981 case AR_inaccessible: 982 S.Diag(D->getLocation(), diag::note_access_protected_restricted) 983 << (InstanceContext != Target.getNamingClass()->getCanonicalDecl()) 984 << S.Context.getTypeDeclType(InstanceContext) 985 << S.Context.getTypeDeclType(ECRecord); 986 return true; 987 } 988 } 989 990 return false; 991} 992 993/// Diagnose the path which caused the given declaration or base class 994/// to become inaccessible. 995static void DiagnoseAccessPath(Sema &S, 996 const EffectiveContext &EC, 997 AccessTarget &Entity) { 998 AccessSpecifier Access = Entity.getAccess(); 999 const CXXRecordDecl *NamingClass = Entity.getNamingClass(); 1000 NamingClass = NamingClass->getCanonicalDecl(); 1001 1002 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); 1003 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 1004 1005 // Easy case: the decl's natural access determined its path access. 1006 // We have to check against AS_private here in case Access is AS_none, 1007 // indicating a non-public member of a private base class. 1008 if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) { 1009 switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) { 1010 case AR_inaccessible: { 1011 if (Access == AS_protected && 1012 TryDiagnoseProtectedAccess(S, EC, Entity)) 1013 return; 1014 1015 // Find an original declaration. 1016 while (D->isOutOfLine()) { 1017 NamedDecl *PrevDecl = 0; 1018 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 1019 PrevDecl = VD->getPreviousDeclaration(); 1020 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 1021 PrevDecl = FD->getPreviousDeclaration(); 1022 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) 1023 PrevDecl = TND->getPreviousDeclaration(); 1024 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 1025 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName()) 1026 break; 1027 PrevDecl = TD->getPreviousDeclaration(); 1028 } 1029 if (!PrevDecl) break; 1030 D = PrevDecl; 1031 } 1032 1033 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D); 1034 Decl *ImmediateChild; 1035 if (D->getDeclContext() == DeclaringClass) 1036 ImmediateChild = D; 1037 else { 1038 DeclContext *DC = D->getDeclContext(); 1039 while (DC->getParent() != DeclaringClass) 1040 DC = DC->getParent(); 1041 ImmediateChild = cast<Decl>(DC); 1042 } 1043 1044 // Check whether there's an AccessSpecDecl preceding this in the 1045 // chain of the DeclContext. 1046 bool Implicit = true; 1047 for (CXXRecordDecl::decl_iterator 1048 I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end(); 1049 I != E; ++I) { 1050 if (*I == ImmediateChild) break; 1051 if (isa<AccessSpecDecl>(*I)) { 1052 Implicit = false; 1053 break; 1054 } 1055 } 1056 1057 S.Diag(D->getLocation(), diag::note_access_natural) 1058 << (unsigned) (Access == AS_protected) 1059 << Implicit; 1060 return; 1061 } 1062 1063 case AR_accessible: break; 1064 1065 case AR_dependent: 1066 llvm_unreachable("can't diagnose dependent access failures"); 1067 return; 1068 } 1069 } 1070 1071 CXXBasePaths Paths; 1072 CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths); 1073 1074 CXXBasePath::iterator I = Path.end(), E = Path.begin(); 1075 while (I != E) { 1076 --I; 1077 1078 const CXXBaseSpecifier *BS = I->Base; 1079 AccessSpecifier BaseAccess = BS->getAccessSpecifier(); 1080 1081 // If this is public inheritance, or the derived class is a friend, 1082 // skip this step. 1083 if (BaseAccess == AS_public) 1084 continue; 1085 1086 switch (GetFriendKind(S, EC, I->Class)) { 1087 case AR_accessible: continue; 1088 case AR_inaccessible: break; 1089 case AR_dependent: 1090 llvm_unreachable("can't diagnose dependent access failures"); 1091 } 1092 1093 // Check whether this base specifier is the tighest point 1094 // constraining access. We have to check against AS_private for 1095 // the same reasons as above. 1096 if (BaseAccess == AS_private || BaseAccess >= Access) { 1097 1098 // We're constrained by inheritance, but we want to say 1099 // "declared private here" if we're diagnosing a hierarchy 1100 // conversion and this is the final step. 1101 unsigned diagnostic; 1102 if (D) diagnostic = diag::note_access_constrained_by_path; 1103 else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural; 1104 else diagnostic = diag::note_access_constrained_by_path; 1105 1106 S.Diag(BS->getSourceRange().getBegin(), diagnostic) 1107 << BS->getSourceRange() 1108 << (BaseAccess == AS_protected) 1109 << (BS->getAccessSpecifierAsWritten() == AS_none); 1110 1111 if (D) 1112 S.Diag(D->getLocation(), diag::note_field_decl); 1113 1114 return; 1115 } 1116 } 1117 1118 llvm_unreachable("access not apparently constrained by path"); 1119} 1120 1121static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, 1122 const EffectiveContext &EC, 1123 AccessTarget &Entity) { 1124 const CXXRecordDecl *NamingClass = Entity.getNamingClass(); 1125 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 1126 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); 1127 1128 S.Diag(Loc, Entity.getDiag()) 1129 << (Entity.getAccess() == AS_protected) 1130 << (D ? D->getDeclName() : DeclarationName()) 1131 << S.Context.getTypeDeclType(NamingClass) 1132 << S.Context.getTypeDeclType(DeclaringClass); 1133 DiagnoseAccessPath(S, EC, Entity); 1134} 1135 1136/// MSVC has a bug where if during an using declaration name lookup, 1137/// the declaration found is unaccessible (private) and that declaration 1138/// was bring into scope via another using declaration whose target 1139/// declaration is accessible (public) then no error is generated. 1140/// Example: 1141/// class A { 1142/// public: 1143/// int f(); 1144/// }; 1145/// class B : public A { 1146/// private: 1147/// using A::f; 1148/// }; 1149/// class C : public B { 1150/// private: 1151/// using B::f; 1152/// }; 1153/// 1154/// Here, B::f is private so this should fail in Standard C++, but 1155/// because B::f refers to A::f which is public MSVC accepts it. 1156static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S, 1157 SourceLocation AccessLoc, 1158 AccessTarget &Entity) { 1159 if (UsingShadowDecl *Shadow = 1160 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) { 1161 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl(); 1162 if (Entity.getTargetDecl()->getAccess() == AS_private && 1163 (OrigDecl->getAccess() == AS_public || 1164 OrigDecl->getAccess() == AS_protected)) { 1165 S.Diag(AccessLoc, diag::war_ms_using_declaration_inaccessible) 1166 << Shadow->getUsingDecl()->getQualifiedNameAsString() 1167 << OrigDecl->getQualifiedNameAsString(); 1168 return true; 1169 } 1170 } 1171 return false; 1172} 1173 1174/// Determines whether the accessed entity is accessible. Public members 1175/// have been weeded out by this point. 1176static AccessResult IsAccessible(Sema &S, 1177 const EffectiveContext &EC, 1178 AccessTarget &Entity) { 1179 // Determine the actual naming class. 1180 CXXRecordDecl *NamingClass = Entity.getNamingClass(); 1181 while (NamingClass->isAnonymousStructOrUnion()) 1182 NamingClass = cast<CXXRecordDecl>(NamingClass->getParent()); 1183 NamingClass = NamingClass->getCanonicalDecl(); 1184 1185 AccessSpecifier UnprivilegedAccess = Entity.getAccess(); 1186 assert(UnprivilegedAccess != AS_public && "public access not weeded out"); 1187 1188 // Before we try to recalculate access paths, try to white-list 1189 // accesses which just trade in on the final step, i.e. accesses 1190 // which don't require [M4] or [B4]. These are by far the most 1191 // common forms of privileged access. 1192 if (UnprivilegedAccess != AS_none) { 1193 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) { 1194 case AR_dependent: 1195 // This is actually an interesting policy decision. We don't 1196 // *have* to delay immediately here: we can do the full access 1197 // calculation in the hope that friendship on some intermediate 1198 // class will make the declaration accessible non-dependently. 1199 // But that's not cheap, and odds are very good (note: assertion 1200 // made without data) that the friend declaration will determine 1201 // access. 1202 return AR_dependent; 1203 1204 case AR_accessible: return AR_accessible; 1205 case AR_inaccessible: break; 1206 } 1207 } 1208 1209 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext(); 1210 1211 // We lower member accesses to base accesses by pretending that the 1212 // member is a base class of its declaring class. 1213 AccessSpecifier FinalAccess; 1214 1215 if (Entity.isMemberAccess()) { 1216 // Determine if the declaration is accessible from EC when named 1217 // in its declaring class. 1218 NamedDecl *Target = Entity.getTargetDecl(); 1219 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 1220 1221 FinalAccess = Target->getAccess(); 1222 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) { 1223 case AR_accessible: 1224 FinalAccess = AS_public; 1225 break; 1226 case AR_inaccessible: break; 1227 case AR_dependent: return AR_dependent; // see above 1228 } 1229 1230 if (DeclaringClass == NamingClass) 1231 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible); 1232 1233 Entity.suppressInstanceContext(); 1234 } else { 1235 FinalAccess = AS_public; 1236 } 1237 1238 assert(Entity.getDeclaringClass() != NamingClass); 1239 1240 // Append the declaration's access if applicable. 1241 CXXBasePaths Paths; 1242 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths); 1243 if (!Path) 1244 return AR_dependent; 1245 1246 assert(Path->Access <= UnprivilegedAccess && 1247 "access along best path worse than direct?"); 1248 if (Path->Access == AS_public) 1249 return AR_accessible; 1250 return AR_inaccessible; 1251} 1252 1253static void DelayDependentAccess(Sema &S, 1254 const EffectiveContext &EC, 1255 SourceLocation Loc, 1256 const AccessTarget &Entity) { 1257 assert(EC.isDependent() && "delaying non-dependent access"); 1258 DeclContext *DC = EC.getInnerContext(); 1259 assert(DC->isDependentContext() && "delaying non-dependent access"); 1260 DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access, 1261 Loc, 1262 Entity.isMemberAccess(), 1263 Entity.getAccess(), 1264 Entity.getTargetDecl(), 1265 Entity.getNamingClass(), 1266 Entity.getBaseObjectType(), 1267 Entity.getDiag()); 1268} 1269 1270/// Checks access to an entity from the given effective context. 1271static AccessResult CheckEffectiveAccess(Sema &S, 1272 const EffectiveContext &EC, 1273 SourceLocation Loc, 1274 AccessTarget &Entity) { 1275 assert(Entity.getAccess() != AS_public && "called for public access!"); 1276 1277 if (S.getLangOptions().MicrosoftMode && 1278 IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity)) 1279 return AR_accessible; 1280 1281 switch (IsAccessible(S, EC, Entity)) { 1282 case AR_dependent: 1283 DelayDependentAccess(S, EC, Loc, Entity); 1284 return AR_dependent; 1285 1286 case AR_inaccessible: 1287 if (!Entity.isQuiet()) 1288 DiagnoseBadAccess(S, Loc, EC, Entity); 1289 return AR_inaccessible; 1290 1291 case AR_accessible: 1292 return AR_accessible; 1293 } 1294 1295 // silence unnecessary warning 1296 llvm_unreachable("invalid access result"); 1297 return AR_accessible; 1298} 1299 1300static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, 1301 AccessTarget &Entity) { 1302 // If the access path is public, it's accessible everywhere. 1303 if (Entity.getAccess() == AS_public) 1304 return Sema::AR_accessible; 1305 1306 if (S.SuppressAccessChecking) 1307 return Sema::AR_accessible; 1308 1309 // If we're currently parsing a declaration, we may need to delay 1310 // access control checking, because our effective context might be 1311 // different based on what the declaration comes out as. 1312 // 1313 // For example, we might be parsing a declaration with a scope 1314 // specifier, like this: 1315 // A::private_type A::foo() { ... } 1316 // 1317 // Or we might be parsing something that will turn out to be a friend: 1318 // void foo(A::private_type); 1319 // void B::foo(A::private_type); 1320 if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { 1321 S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); 1322 return Sema::AR_delayed; 1323 } 1324 1325 EffectiveContext EC(S.CurContext); 1326 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) { 1327 case AR_accessible: return Sema::AR_accessible; 1328 case AR_inaccessible: return Sema::AR_inaccessible; 1329 case AR_dependent: return Sema::AR_dependent; 1330 } 1331 llvm_unreachable("falling off end"); 1332 return Sema::AR_accessible; 1333} 1334 1335void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) { 1336 // Access control for names used in the declarations of functions 1337 // and function templates should normally be evaluated in the context 1338 // of the declaration, just in case it's a friend of something. 1339 // However, this does not apply to local extern declarations. 1340 1341 DeclContext *DC = decl->getDeclContext(); 1342 if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) { 1343 if (!DC->isFunctionOrMethod()) DC = fn; 1344 } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) { 1345 // Never a local declaration. 1346 DC = fnt->getTemplatedDecl(); 1347 } 1348 1349 EffectiveContext EC(DC); 1350 1351 AccessTarget Target(DD.getAccessData()); 1352 1353 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible) 1354 DD.Triggered = true; 1355} 1356 1357void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD, 1358 const MultiLevelTemplateArgumentList &TemplateArgs) { 1359 SourceLocation Loc = DD.getAccessLoc(); 1360 AccessSpecifier Access = DD.getAccess(); 1361 1362 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(), 1363 TemplateArgs); 1364 if (!NamingD) return; 1365 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(), 1366 TemplateArgs); 1367 if (!TargetD) return; 1368 1369 if (DD.isAccessToMember()) { 1370 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD); 1371 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD); 1372 QualType BaseObjectType = DD.getAccessBaseObjectType(); 1373 if (!BaseObjectType.isNull()) { 1374 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc, 1375 DeclarationName()); 1376 if (BaseObjectType.isNull()) return; 1377 } 1378 1379 AccessTarget Entity(Context, 1380 AccessTarget::Member, 1381 NamingClass, 1382 DeclAccessPair::make(TargetDecl, Access), 1383 BaseObjectType); 1384 Entity.setDiag(DD.getDiagnostic()); 1385 CheckAccess(*this, Loc, Entity); 1386 } else { 1387 AccessTarget Entity(Context, 1388 AccessTarget::Base, 1389 cast<CXXRecordDecl>(TargetD), 1390 cast<CXXRecordDecl>(NamingD), 1391 Access); 1392 Entity.setDiag(DD.getDiagnostic()); 1393 CheckAccess(*this, Loc, Entity); 1394 } 1395} 1396 1397Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, 1398 DeclAccessPair Found) { 1399 if (!getLangOptions().AccessControl || 1400 !E->getNamingClass() || 1401 Found.getAccess() == AS_public) 1402 return AR_accessible; 1403 1404 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 1405 Found, QualType()); 1406 Entity.setDiag(diag::err_access) << E->getSourceRange(); 1407 1408 return CheckAccess(*this, E->getNameLoc(), Entity); 1409} 1410 1411/// Perform access-control checking on a previously-unresolved member 1412/// access which has now been resolved to a member. 1413Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, 1414 DeclAccessPair Found) { 1415 if (!getLangOptions().AccessControl || 1416 Found.getAccess() == AS_public) 1417 return AR_accessible; 1418 1419 QualType BaseType = E->getBaseType(); 1420 if (E->isArrow()) 1421 BaseType = BaseType->getAs<PointerType>()->getPointeeType(); 1422 1423 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 1424 Found, BaseType); 1425 Entity.setDiag(diag::err_access) << E->getSourceRange(); 1426 1427 return CheckAccess(*this, E->getMemberLoc(), Entity); 1428} 1429 1430Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, 1431 CXXDestructorDecl *Dtor, 1432 const PartialDiagnostic &PDiag) { 1433 if (!getLangOptions().AccessControl) 1434 return AR_accessible; 1435 1436 // There's never a path involved when checking implicit destructor access. 1437 AccessSpecifier Access = Dtor->getAccess(); 1438 if (Access == AS_public) 1439 return AR_accessible; 1440 1441 CXXRecordDecl *NamingClass = Dtor->getParent(); 1442 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 1443 DeclAccessPair::make(Dtor, Access), 1444 QualType()); 1445 Entity.setDiag(PDiag); // TODO: avoid copy 1446 1447 return CheckAccess(*this, Loc, Entity); 1448} 1449 1450/// Checks access to a constructor. 1451Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, 1452 CXXConstructorDecl *Constructor, 1453 const InitializedEntity &Entity, 1454 AccessSpecifier Access, 1455 bool IsCopyBindingRefToTemp) { 1456 if (!getLangOptions().AccessControl || 1457 Access == AS_public) 1458 return AR_accessible; 1459 1460 CXXRecordDecl *NamingClass = Constructor->getParent(); 1461 AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass, 1462 DeclAccessPair::make(Constructor, Access), 1463 QualType()); 1464 PartialDiagnostic PD(PDiag()); 1465 switch (Entity.getKind()) { 1466 default: 1467 PD = PDiag(IsCopyBindingRefToTemp 1468 ? diag::ext_rvalue_to_reference_access_ctor 1469 : diag::err_access_ctor); 1470 1471 break; 1472 1473 case InitializedEntity::EK_Base: 1474 PD = PDiag(diag::err_access_base_ctor); 1475 PD << Entity.isInheritedVirtualBase() 1476 << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor); 1477 break; 1478 1479 case InitializedEntity::EK_Member: { 1480 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl()); 1481 PD = PDiag(diag::err_access_field_ctor); 1482 PD << Field->getType() << getSpecialMember(Constructor); 1483 break; 1484 } 1485 1486 } 1487 1488 return CheckConstructorAccess(UseLoc, Constructor, Access, PD); 1489} 1490 1491/// Checks access to a constructor. 1492Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, 1493 CXXConstructorDecl *Constructor, 1494 AccessSpecifier Access, 1495 PartialDiagnostic PD) { 1496 if (!getLangOptions().AccessControl || 1497 Access == AS_public) 1498 return AR_accessible; 1499 1500 CXXRecordDecl *NamingClass = Constructor->getParent(); 1501 AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass, 1502 DeclAccessPair::make(Constructor, Access), 1503 QualType()); 1504 AccessEntity.setDiag(PD); 1505 1506 return CheckAccess(*this, UseLoc, AccessEntity); 1507} 1508 1509/// Checks direct (i.e. non-inherited) access to an arbitrary class 1510/// member. 1511Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc, 1512 NamedDecl *Target, 1513 const PartialDiagnostic &Diag) { 1514 AccessSpecifier Access = Target->getAccess(); 1515 if (!getLangOptions().AccessControl || 1516 Access == AS_public) 1517 return AR_accessible; 1518 1519 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext()); 1520 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 1521 DeclAccessPair::make(Target, Access), 1522 QualType()); 1523 Entity.setDiag(Diag); 1524 return CheckAccess(*this, UseLoc, Entity); 1525} 1526 1527 1528/// Checks access to an overloaded operator new or delete. 1529Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, 1530 SourceRange PlacementRange, 1531 CXXRecordDecl *NamingClass, 1532 DeclAccessPair Found, 1533 bool Diagnose) { 1534 if (!getLangOptions().AccessControl || 1535 !NamingClass || 1536 Found.getAccess() == AS_public) 1537 return AR_accessible; 1538 1539 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1540 QualType()); 1541 if (Diagnose) 1542 Entity.setDiag(diag::err_access) 1543 << PlacementRange; 1544 1545 return CheckAccess(*this, OpLoc, Entity); 1546} 1547 1548/// Checks access to an overloaded member operator, including 1549/// conversion operators. 1550Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, 1551 Expr *ObjectExpr, 1552 Expr *ArgExpr, 1553 DeclAccessPair Found) { 1554 if (!getLangOptions().AccessControl || 1555 Found.getAccess() == AS_public) 1556 return AR_accessible; 1557 1558 const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>(); 1559 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl()); 1560 1561 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1562 ObjectExpr->getType()); 1563 Entity.setDiag(diag::err_access) 1564 << ObjectExpr->getSourceRange() 1565 << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); 1566 1567 return CheckAccess(*this, OpLoc, Entity); 1568} 1569 1570Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr, 1571 DeclAccessPair Found) { 1572 if (!getLangOptions().AccessControl || 1573 Found.getAccess() == AS_none || 1574 Found.getAccess() == AS_public) 1575 return AR_accessible; 1576 1577 OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression; 1578 CXXRecordDecl *NamingClass = Ovl->getNamingClass(); 1579 1580 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1581 Context.getTypeDeclType(NamingClass)); 1582 Entity.setDiag(diag::err_access) 1583 << Ovl->getSourceRange(); 1584 1585 return CheckAccess(*this, Ovl->getNameLoc(), Entity); 1586} 1587 1588/// Checks access for a hierarchy conversion. 1589/// 1590/// \param IsBaseToDerived whether this is a base-to-derived conversion (true) 1591/// or a derived-to-base conversion (false) 1592/// \param ForceCheck true if this check should be performed even if access 1593/// control is disabled; some things rely on this for semantics 1594/// \param ForceUnprivileged true if this check should proceed as if the 1595/// context had no special privileges 1596/// \param ADK controls the kind of diagnostics that are used 1597Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, 1598 QualType Base, 1599 QualType Derived, 1600 const CXXBasePath &Path, 1601 unsigned DiagID, 1602 bool ForceCheck, 1603 bool ForceUnprivileged) { 1604 if (!ForceCheck && !getLangOptions().AccessControl) 1605 return AR_accessible; 1606 1607 if (Path.Access == AS_public) 1608 return AR_accessible; 1609 1610 CXXRecordDecl *BaseD, *DerivedD; 1611 BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl()); 1612 DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl()); 1613 1614 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD, 1615 Path.Access); 1616 if (DiagID) 1617 Entity.setDiag(DiagID) << Derived << Base; 1618 1619 if (ForceUnprivileged) { 1620 switch (CheckEffectiveAccess(*this, EffectiveContext(), 1621 AccessLoc, Entity)) { 1622 case ::AR_accessible: return Sema::AR_accessible; 1623 case ::AR_inaccessible: return Sema::AR_inaccessible; 1624 case ::AR_dependent: return Sema::AR_dependent; 1625 } 1626 llvm_unreachable("unexpected result from CheckEffectiveAccess"); 1627 } 1628 return CheckAccess(*this, AccessLoc, Entity); 1629} 1630 1631/// Checks access to all the declarations in the given result set. 1632void Sema::CheckLookupAccess(const LookupResult &R) { 1633 assert(getLangOptions().AccessControl 1634 && "performing access check without access control"); 1635 assert(R.getNamingClass() && "performing access check without naming class"); 1636 1637 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { 1638 if (I.getAccess() != AS_public) { 1639 AccessTarget Entity(Context, AccessedEntity::Member, 1640 R.getNamingClass(), I.getPair(), 1641 R.getBaseObjectType()); 1642 Entity.setDiag(diag::err_access); 1643 CheckAccess(*this, R.getNameLoc(), Entity); 1644 } 1645 } 1646} 1647 1648/// Checks access to Decl from the given class. The check will take access 1649/// specifiers into account, but no member access expressions and such. 1650/// 1651/// \param Decl the declaration to check if it can be accessed 1652/// \param Class the class/context from which to start the search 1653/// \return true if the Decl is accessible from the Class, false otherwise. 1654bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) { 1655 if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) { 1656 if (!Class || !Decl->isCXXClassMember()) 1657 return true; 1658 1659 QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal(); 1660 AccessTarget Entity(Context, AccessedEntity::Member, Class, 1661 DeclAccessPair::make(Decl, Decl->getAccess()), 1662 qType); 1663 if (Entity.getAccess() == AS_public) 1664 return true; 1665 1666 EffectiveContext EC(CurContext); 1667 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible; 1668 } 1669 1670 // FIXME: Check access for Objective-C ivars. 1671 return true; 1672} 1673 1674void Sema::ActOnStartSuppressingAccessChecks() { 1675 assert(!SuppressAccessChecking && 1676 "Tried to start access check suppression when already started."); 1677 SuppressAccessChecking = true; 1678} 1679 1680void Sema::ActOnStopSuppressingAccessChecks() { 1681 assert(SuppressAccessChecking && 1682 "Tried to stop access check suprression when already stopped."); 1683 SuppressAccessChecking = false; 1684} 1685