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