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