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