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