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