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