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