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