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