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