SemaAccess.cpp revision c91cc66e92b084acd1fdbaa1c3c74242741b3d46
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 "Sema.h" 15#include "Lookup.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/CXXInheritance.h" 18#include "clang/AST/DeclCXX.h" 19#include "clang/AST/DeclFriend.h" 20#include "clang/AST/DependentDiagnostic.h" 21#include "clang/AST/ExprCXX.h" 22 23using namespace clang; 24 25/// A copy of Sema's enum without AR_delayed. 26enum AccessResult { 27 AR_accessible, 28 AR_inaccessible, 29 AR_dependent 30}; 31 32/// SetMemberAccessSpecifier - Set the access specifier of a member. 33/// Returns true on error (when the previous member decl access specifier 34/// is different from the new member decl access specifier). 35bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl, 36 NamedDecl *PrevMemberDecl, 37 AccessSpecifier LexicalAS) { 38 if (!PrevMemberDecl) { 39 // Use the lexical access specifier. 40 MemberDecl->setAccess(LexicalAS); 41 return false; 42 } 43 44 // C++ [class.access.spec]p3: When a member is redeclared its access 45 // specifier must be same as its initial declaration. 46 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) { 47 Diag(MemberDecl->getLocation(), 48 diag::err_class_redeclared_with_different_access) 49 << MemberDecl << LexicalAS; 50 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration) 51 << PrevMemberDecl << PrevMemberDecl->getAccess(); 52 53 MemberDecl->setAccess(LexicalAS); 54 return true; 55 } 56 57 MemberDecl->setAccess(PrevMemberDecl->getAccess()); 58 return false; 59} 60 61static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) { 62 DeclContext *DC = D->getDeclContext(); 63 64 // This can only happen at top: enum decls only "publish" their 65 // immediate members. 66 if (isa<EnumDecl>(DC)) 67 DC = cast<EnumDecl>(DC)->getDeclContext(); 68 69 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC); 70 while (DeclaringClass->isAnonymousStructOrUnion()) 71 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext()); 72 return DeclaringClass; 73} 74 75namespace { 76struct EffectiveContext { 77 EffectiveContext() : Inner(0), Dependent(false) {} 78 79 explicit EffectiveContext(DeclContext *DC) 80 : Inner(DC), 81 Dependent(DC->isDependentContext()) { 82 83 // C++ [class.access.nest]p1: 84 // A nested class is a member and as such has the same access 85 // rights as any other member. 86 // C++ [class.access]p2: 87 // A member of a class can also access all the names to which 88 // the class has access. A local class of a member function 89 // may access the same names that the member function itself 90 // may access. 91 // This almost implies that the privileges of nesting are transitive. 92 // Technically it says nothing about the local classes of non-member 93 // functions (which can gain privileges through friendship), but we 94 // take that as an oversight. 95 while (true) { 96 if (isa<CXXRecordDecl>(DC)) { 97 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl(); 98 Records.push_back(Record); 99 DC = Record->getDeclContext(); 100 } else if (isa<FunctionDecl>(DC)) { 101 FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl(); 102 Functions.push_back(Function); 103 DC = Function->getDeclContext(); 104 } else if (DC->isFileContext()) { 105 break; 106 } else { 107 DC = DC->getParent(); 108 } 109 } 110 } 111 112 bool isDependent() const { return Dependent; } 113 114 bool includesClass(const CXXRecordDecl *R) const { 115 R = R->getCanonicalDecl(); 116 return std::find(Records.begin(), Records.end(), R) 117 != Records.end(); 118 } 119 120 /// Retrieves the innermost "useful" context. Can be null if we're 121 /// doing access-control without privileges. 122 DeclContext *getInnerContext() const { 123 return Inner; 124 } 125 126 typedef llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator; 127 128 DeclContext *Inner; 129 llvm::SmallVector<FunctionDecl*, 4> Functions; 130 llvm::SmallVector<CXXRecordDecl*, 4> Records; 131 bool Dependent; 132}; 133 134/// Like Sema's AccessedEntity, but kindly lets us scribble all over 135/// it. 136struct AccessTarget : public Sema::AccessedEntity { 137 AccessTarget(const Sema::AccessedEntity &Entity) 138 : AccessedEntity(Entity) { 139 initialize(); 140 } 141 142 AccessTarget(ASTContext &Context, 143 MemberNonce _, 144 CXXRecordDecl *NamingClass, 145 DeclAccessPair FoundDecl, 146 QualType BaseObjectType) 147 : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) { 148 initialize(); 149 } 150 151 AccessTarget(ASTContext &Context, 152 BaseNonce _, 153 CXXRecordDecl *BaseClass, 154 CXXRecordDecl *DerivedClass, 155 AccessSpecifier Access) 156 : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) { 157 initialize(); 158 } 159 160 bool hasInstanceContext() const { 161 return HasInstanceContext; 162 } 163 164 class SavedInstanceContext { 165 public: 166 ~SavedInstanceContext() { 167 Target.HasInstanceContext = Has; 168 } 169 170 private: 171 friend struct AccessTarget; 172 explicit SavedInstanceContext(AccessTarget &Target) 173 : Target(Target), Has(Target.HasInstanceContext) {} 174 AccessTarget &Target; 175 bool Has; 176 }; 177 178 SavedInstanceContext saveInstanceContext() { 179 return SavedInstanceContext(*this); 180 } 181 182 void suppressInstanceContext() { 183 HasInstanceContext = false; 184 } 185 186 const CXXRecordDecl *resolveInstanceContext(Sema &S) const { 187 assert(HasInstanceContext); 188 if (CalculatedInstanceContext) 189 return InstanceContext; 190 191 CalculatedInstanceContext = true; 192 DeclContext *IC = S.computeDeclContext(getBaseObjectType()); 193 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0); 194 return InstanceContext; 195 } 196 197 const CXXRecordDecl *getDeclaringClass() const { 198 return DeclaringClass; 199 } 200 201private: 202 void initialize() { 203 HasInstanceContext = (isMemberAccess() && 204 !getBaseObjectType().isNull() && 205 getTargetDecl()->isCXXInstanceMember()); 206 CalculatedInstanceContext = false; 207 InstanceContext = 0; 208 209 if (isMemberAccess()) 210 DeclaringClass = FindDeclaringClass(getTargetDecl()); 211 else 212 DeclaringClass = getBaseClass(); 213 DeclaringClass = DeclaringClass->getCanonicalDecl(); 214 } 215 216 bool HasInstanceContext : 1; 217 mutable bool CalculatedInstanceContext : 1; 218 mutable const CXXRecordDecl *InstanceContext; 219 const CXXRecordDecl *DeclaringClass; 220}; 221 222} 223 224/// Checks whether one class is derived from another, inclusively. 225/// Properly indicates when it couldn't be determined due to 226/// dependence. 227/// 228/// This should probably be donated to AST or at least Sema. 229static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, 230 const CXXRecordDecl *Target) { 231 assert(Derived->getCanonicalDecl() == Derived); 232 assert(Target->getCanonicalDecl() == Target); 233 234 if (Derived == Target) return AR_accessible; 235 236 AccessResult OnFailure = AR_inaccessible; 237 llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack 238 239 while (true) { 240 for (CXXRecordDecl::base_class_const_iterator 241 I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) { 242 243 const CXXRecordDecl *RD; 244 245 QualType T = I->getType(); 246 if (const RecordType *RT = T->getAs<RecordType>()) { 247 RD = cast<CXXRecordDecl>(RT->getDecl()); 248 } else { 249 // It's possible for a base class to be the current 250 // instantiation of some enclosing template, but I'm guessing 251 // nobody will ever care that we just dependently delay here. 252 assert(T->isDependentType() && "non-dependent base wasn't a record?"); 253 OnFailure = AR_dependent; 254 continue; 255 } 256 257 RD = RD->getCanonicalDecl(); 258 if (RD == Target) return AR_accessible; 259 Queue.push_back(RD); 260 } 261 262 if (Queue.empty()) break; 263 264 Derived = Queue.back(); 265 Queue.pop_back(); 266 } 267 268 return OnFailure; 269} 270 271 272static bool MightInstantiateTo(Sema &S, DeclContext *Context, 273 DeclContext *Friend) { 274 if (Friend == Context) 275 return true; 276 277 assert(!Friend->isDependentContext() && 278 "can't handle friends with dependent contexts here"); 279 280 if (!Context->isDependentContext()) 281 return false; 282 283 if (Friend->isFileContext()) 284 return false; 285 286 // TODO: this is very conservative 287 return true; 288} 289 290// Asks whether the type in 'context' can ever instantiate to the type 291// in 'friend'. 292static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) { 293 if (Friend == Context) 294 return true; 295 296 if (!Friend->isDependentType() && !Context->isDependentType()) 297 return false; 298 299 // TODO: this is very conservative. 300 return true; 301} 302 303static bool MightInstantiateTo(Sema &S, 304 FunctionDecl *Context, 305 FunctionDecl *Friend) { 306 if (Context->getDeclName() != Friend->getDeclName()) 307 return false; 308 309 if (!MightInstantiateTo(S, 310 Context->getDeclContext(), 311 Friend->getDeclContext())) 312 return false; 313 314 CanQual<FunctionProtoType> FriendTy 315 = S.Context.getCanonicalType(Friend->getType()) 316 ->getAs<FunctionProtoType>(); 317 CanQual<FunctionProtoType> ContextTy 318 = S.Context.getCanonicalType(Context->getType()) 319 ->getAs<FunctionProtoType>(); 320 321 // There isn't any way that I know of to add qualifiers 322 // during instantiation. 323 if (FriendTy.getQualifiers() != ContextTy.getQualifiers()) 324 return false; 325 326 if (FriendTy->getNumArgs() != ContextTy->getNumArgs()) 327 return false; 328 329 if (!MightInstantiateTo(S, 330 ContextTy->getResultType(), 331 FriendTy->getResultType())) 332 return false; 333 334 for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I) 335 if (!MightInstantiateTo(S, 336 ContextTy->getArgType(I), 337 FriendTy->getArgType(I))) 338 return false; 339 340 return true; 341} 342 343static bool MightInstantiateTo(Sema &S, 344 FunctionTemplateDecl *Context, 345 FunctionTemplateDecl *Friend) { 346 return MightInstantiateTo(S, 347 Context->getTemplatedDecl(), 348 Friend->getTemplatedDecl()); 349} 350 351static AccessResult MatchesFriend(Sema &S, 352 const EffectiveContext &EC, 353 const CXXRecordDecl *Friend) { 354 if (EC.includesClass(Friend)) 355 return AR_accessible; 356 357 if (EC.isDependent()) { 358 CanQualType FriendTy 359 = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend)); 360 361 for (EffectiveContext::record_iterator 362 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 363 CanQualType ContextTy 364 = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I)); 365 if (MightInstantiateTo(S, ContextTy, FriendTy)) 366 return AR_dependent; 367 } 368 } 369 370 return AR_inaccessible; 371} 372 373static AccessResult MatchesFriend(Sema &S, 374 const EffectiveContext &EC, 375 CanQualType Friend) { 376 if (const RecordType *RT = Friend->getAs<RecordType>()) 377 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl())); 378 379 // TODO: we can do better than this 380 if (Friend->isDependentType()) 381 return AR_dependent; 382 383 return AR_inaccessible; 384} 385 386/// Determines whether the given friend class template matches 387/// anything in the effective context. 388static AccessResult MatchesFriend(Sema &S, 389 const EffectiveContext &EC, 390 ClassTemplateDecl *Friend) { 391 AccessResult OnFailure = AR_inaccessible; 392 393 // Check whether the friend is the template of a class in the 394 // context chain. 395 for (llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator 396 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 397 CXXRecordDecl *Record = *I; 398 399 // Figure out whether the current class has a template: 400 ClassTemplateDecl *CTD; 401 402 // A specialization of the template... 403 if (isa<ClassTemplateSpecializationDecl>(Record)) { 404 CTD = cast<ClassTemplateSpecializationDecl>(Record) 405 ->getSpecializedTemplate(); 406 407 // ... or the template pattern itself. 408 } else { 409 CTD = Record->getDescribedClassTemplate(); 410 if (!CTD) continue; 411 } 412 413 // It's a match. 414 if (Friend == CTD->getCanonicalDecl()) 415 return AR_accessible; 416 417 // If the context isn't dependent, it can't be a dependent match. 418 if (!EC.isDependent()) 419 continue; 420 421 // If the template names don't match, it can't be a dependent 422 // match. This isn't true in C++0x because of template aliases. 423 if (!S.LangOpts.CPlusPlus0x && CTD->getDeclName() != Friend->getDeclName()) 424 continue; 425 426 // If the class's context can't instantiate to the friend's 427 // context, it can't be a dependent match. 428 if (!MightInstantiateTo(S, CTD->getDeclContext(), 429 Friend->getDeclContext())) 430 continue; 431 432 // Otherwise, it's a dependent match. 433 OnFailure = AR_dependent; 434 } 435 436 return OnFailure; 437} 438 439/// Determines whether the given friend function matches anything in 440/// the effective context. 441static AccessResult MatchesFriend(Sema &S, 442 const EffectiveContext &EC, 443 FunctionDecl *Friend) { 444 AccessResult OnFailure = AR_inaccessible; 445 446 for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator 447 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 448 if (Friend == *I) 449 return AR_accessible; 450 451 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend)) 452 OnFailure = AR_dependent; 453 } 454 455 return OnFailure; 456} 457 458/// Determines whether the given friend function template matches 459/// anything in the effective context. 460static AccessResult MatchesFriend(Sema &S, 461 const EffectiveContext &EC, 462 FunctionTemplateDecl *Friend) { 463 if (EC.Functions.empty()) return AR_inaccessible; 464 465 AccessResult OnFailure = AR_inaccessible; 466 467 for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator 468 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) { 469 470 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate(); 471 if (!FTD) 472 FTD = (*I)->getDescribedFunctionTemplate(); 473 if (!FTD) 474 continue; 475 476 FTD = FTD->getCanonicalDecl(); 477 478 if (Friend == FTD) 479 return AR_accessible; 480 481 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend)) 482 OnFailure = AR_dependent; 483 } 484 485 return OnFailure; 486} 487 488/// Determines whether the given friend declaration matches anything 489/// in the effective context. 490static AccessResult MatchesFriend(Sema &S, 491 const EffectiveContext &EC, 492 FriendDecl *FriendD) { 493 if (TypeSourceInfo *T = FriendD->getFriendType()) 494 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified()); 495 496 NamedDecl *Friend 497 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl()); 498 499 // FIXME: declarations with dependent or templated scope. 500 501 if (isa<ClassTemplateDecl>(Friend)) 502 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend)); 503 504 if (isa<FunctionTemplateDecl>(Friend)) 505 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend)); 506 507 if (isa<CXXRecordDecl>(Friend)) 508 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend)); 509 510 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind"); 511 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend)); 512} 513 514static AccessResult GetFriendKind(Sema &S, 515 const EffectiveContext &EC, 516 const CXXRecordDecl *Class) { 517 AccessResult OnFailure = AR_inaccessible; 518 519 // Okay, check friends. 520 for (CXXRecordDecl::friend_iterator I = Class->friend_begin(), 521 E = Class->friend_end(); I != E; ++I) { 522 FriendDecl *Friend = *I; 523 524 switch (MatchesFriend(S, EC, Friend)) { 525 case AR_accessible: 526 return AR_accessible; 527 528 case AR_inaccessible: 529 continue; 530 531 case AR_dependent: 532 OnFailure = AR_dependent; 533 break; 534 } 535 } 536 537 // That's it, give up. 538 return OnFailure; 539} 540 541static AccessResult HasAccess(Sema &S, 542 const EffectiveContext &EC, 543 const CXXRecordDecl *NamingClass, 544 AccessSpecifier Access, 545 const AccessTarget &Target) { 546 assert(NamingClass->getCanonicalDecl() == NamingClass && 547 "declaration should be canonicalized before being passed here"); 548 549 if (Access == AS_public) return AR_accessible; 550 assert(Access == AS_private || Access == AS_protected); 551 552 AccessResult OnFailure = AR_inaccessible; 553 554 for (EffectiveContext::record_iterator 555 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { 556 // All the declarations in EC have been canonicalized, so pointer 557 // equality from this point on will work fine. 558 const CXXRecordDecl *ECRecord = *I; 559 560 // [B2] and [M2] 561 if (Access == AS_private) { 562 if (ECRecord == NamingClass) 563 return AR_accessible; 564 565 // [B3] and [M3] 566 } else { 567 assert(Access == AS_protected); 568 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) { 569 case AR_accessible: break; 570 case AR_inaccessible: continue; 571 case AR_dependent: OnFailure = AR_dependent; continue; 572 } 573 574 if (!Target.hasInstanceContext()) 575 return AR_accessible; 576 577 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 578 if (!InstanceContext) { 579 OnFailure = AR_dependent; 580 continue; 581 } 582 583 // C++ [class.protected]p1: 584 // An additional access check beyond those described earlier in 585 // [class.access] is applied when a non-static data member or 586 // non-static member function is a protected member of its naming 587 // class. As described earlier, access to a protected member is 588 // granted because the reference occurs in a friend or member of 589 // some class C. If the access is to form a pointer to member, 590 // the nested-name-specifier shall name C or a class derived from 591 // C. All other accesses involve a (possibly implicit) object 592 // expression. In this case, the class of the object expression 593 // shall be C or a class derived from C. 594 // 595 // We interpret this as a restriction on [M3]. Most of the 596 // conditions are encoded by not having any instance context. 597 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) { 598 case AR_accessible: return AR_accessible; 599 case AR_inaccessible: continue; 600 case AR_dependent: OnFailure = AR_dependent; continue; 601 } 602 } 603 } 604 605 if (!NamingClass->hasFriends()) 606 return OnFailure; 607 608 // Don't consider friends if we're under the [class.protected] 609 // restriction, above. 610 if (Access == AS_protected && Target.hasInstanceContext()) { 611 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S); 612 if (!InstanceContext) return AR_dependent; 613 614 switch (IsDerivedFromInclusive(InstanceContext, NamingClass)) { 615 case AR_accessible: break; 616 case AR_inaccessible: return OnFailure; 617 case AR_dependent: return AR_dependent; 618 } 619 } 620 621 switch (GetFriendKind(S, EC, NamingClass)) { 622 case AR_accessible: return AR_accessible; 623 case AR_inaccessible: return OnFailure; 624 case AR_dependent: return AR_dependent; 625 } 626 627 // Silence bogus warnings 628 llvm_unreachable("impossible friendship kind"); 629 return OnFailure; 630} 631 632/// Finds the best path from the naming class to the declaring class, 633/// taking friend declarations into account. 634/// 635/// C++0x [class.access.base]p5: 636/// A member m is accessible at the point R when named in class N if 637/// [M1] m as a member of N is public, or 638/// [M2] m as a member of N is private, and R occurs in a member or 639/// friend of class N, or 640/// [M3] m as a member of N is protected, and R occurs in a member or 641/// friend of class N, or in a member or friend of a class P 642/// derived from N, where m as a member of P is public, private, 643/// or protected, or 644/// [M4] there exists a base class B of N that is accessible at R, and 645/// m is accessible at R when named in class B. 646/// 647/// C++0x [class.access.base]p4: 648/// A base class B of N is accessible at R, if 649/// [B1] an invented public member of B would be a public member of N, or 650/// [B2] R occurs in a member or friend of class N, and an invented public 651/// member of B would be a private or protected member of N, or 652/// [B3] R occurs in a member or friend of a class P derived from N, and an 653/// invented public member of B would be a private or protected member 654/// of P, or 655/// [B4] there exists a class S such that B is a base class of S accessible 656/// at R and S is a base class of N accessible at R. 657/// 658/// Along a single inheritance path we can restate both of these 659/// iteratively: 660/// 661/// First, we note that M1-4 are equivalent to B1-4 if the member is 662/// treated as a notional base of its declaring class with inheritance 663/// access equivalent to the member's access. Therefore we need only 664/// ask whether a class B is accessible from a class N in context R. 665/// 666/// Let B_1 .. B_n be the inheritance path in question (i.e. where 667/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of 668/// B_i). For i in 1..n, we will calculate ACAB(i), the access to the 669/// closest accessible base in the path: 670/// Access(a, b) = (* access on the base specifier from a to b *) 671/// Merge(a, forbidden) = forbidden 672/// Merge(a, private) = forbidden 673/// Merge(a, b) = min(a,b) 674/// Accessible(c, forbidden) = false 675/// Accessible(c, private) = (R is c) || IsFriend(c, R) 676/// Accessible(c, protected) = (R derived from c) || IsFriend(c, R) 677/// Accessible(c, public) = true 678/// ACAB(n) = public 679/// ACAB(i) = 680/// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in 681/// if Accessible(B_i, AccessToBase) then public else AccessToBase 682/// 683/// B is an accessible base of N at R iff ACAB(1) = public. 684/// 685/// \param FinalAccess the access of the "final step", or AS_public if 686/// there is no final step. 687/// \return null if friendship is dependent 688static CXXBasePath *FindBestPath(Sema &S, 689 const EffectiveContext &EC, 690 AccessTarget &Target, 691 AccessSpecifier FinalAccess, 692 CXXBasePaths &Paths) { 693 // Derive the paths to the desired base. 694 const CXXRecordDecl *Derived = Target.getNamingClass(); 695 const CXXRecordDecl *Base = Target.getDeclaringClass(); 696 697 // FIXME: fail correctly when there are dependent paths. 698 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base), 699 Paths); 700 assert(isDerived && "derived class not actually derived from base"); 701 (void) isDerived; 702 703 CXXBasePath *BestPath = 0; 704 705 assert(FinalAccess != AS_none && "forbidden access after declaring class"); 706 707 bool AnyDependent = false; 708 709 // Derive the friend-modified access along each path. 710 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end(); 711 PI != PE; ++PI) { 712 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext(); 713 714 // Walk through the path backwards. 715 AccessSpecifier PathAccess = FinalAccess; 716 CXXBasePath::iterator I = PI->end(), E = PI->begin(); 717 while (I != E) { 718 --I; 719 720 assert(PathAccess != AS_none); 721 722 // If the declaration is a private member of a base class, there 723 // is no level of friendship in derived classes that can make it 724 // accessible. 725 if (PathAccess == AS_private) { 726 PathAccess = AS_none; 727 break; 728 } 729 730 const CXXRecordDecl *NC = I->Class->getCanonicalDecl(); 731 732 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier(); 733 PathAccess = std::max(PathAccess, BaseAccess); 734 735 switch (HasAccess(S, EC, NC, PathAccess, Target)) { 736 case AR_inaccessible: break; 737 case AR_accessible: 738 PathAccess = AS_public; 739 740 // Future tests are not against members and so do not have 741 // instance context. 742 Target.suppressInstanceContext(); 743 break; 744 case AR_dependent: 745 AnyDependent = true; 746 goto Next; 747 } 748 } 749 750 // Note that we modify the path's Access field to the 751 // friend-modified access. 752 if (BestPath == 0 || PathAccess < BestPath->Access) { 753 BestPath = &*PI; 754 BestPath->Access = PathAccess; 755 756 // Short-circuit if we found a public path. 757 if (BestPath->Access == AS_public) 758 return BestPath; 759 } 760 761 Next: ; 762 } 763 764 assert((!BestPath || BestPath->Access != AS_public) && 765 "fell out of loop with public path"); 766 767 // We didn't find a public path, but at least one path was subject 768 // to dependent friendship, so delay the check. 769 if (AnyDependent) 770 return 0; 771 772 return BestPath; 773} 774 775/// Diagnose the path which caused the given declaration or base class 776/// to become inaccessible. 777static void DiagnoseAccessPath(Sema &S, 778 const EffectiveContext &EC, 779 AccessTarget &Entity) { 780 AccessSpecifier Access = Entity.getAccess(); 781 const CXXRecordDecl *NamingClass = Entity.getNamingClass(); 782 NamingClass = NamingClass->getCanonicalDecl(); 783 784 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); 785 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 786 787 // Easy case: the decl's natural access determined its path access. 788 // We have to check against AS_private here in case Access is AS_none, 789 // indicating a non-public member of a private base class. 790 if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) { 791 switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) { 792 case AR_inaccessible: { 793 S.Diag(D->getLocation(), diag::note_access_natural) 794 << (unsigned) (Access == AS_protected) 795 << /*FIXME: not implicitly*/ 0; 796 return; 797 } 798 799 case AR_accessible: break; 800 801 case AR_dependent: 802 llvm_unreachable("can't diagnose dependent access failures"); 803 return; 804 } 805 } 806 807 CXXBasePaths Paths; 808 CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths); 809 810 CXXBasePath::iterator I = Path.end(), E = Path.begin(); 811 while (I != E) { 812 --I; 813 814 const CXXBaseSpecifier *BS = I->Base; 815 AccessSpecifier BaseAccess = BS->getAccessSpecifier(); 816 817 // If this is public inheritance, or the derived class is a friend, 818 // skip this step. 819 if (BaseAccess == AS_public) 820 continue; 821 822 switch (GetFriendKind(S, EC, I->Class)) { 823 case AR_accessible: continue; 824 case AR_inaccessible: break; 825 case AR_dependent: 826 llvm_unreachable("can't diagnose dependent access failures"); 827 } 828 829 // Check whether this base specifier is the tighest point 830 // constraining access. We have to check against AS_private for 831 // the same reasons as above. 832 if (BaseAccess == AS_private || BaseAccess >= Access) { 833 834 // We're constrained by inheritance, but we want to say 835 // "declared private here" if we're diagnosing a hierarchy 836 // conversion and this is the final step. 837 unsigned diagnostic; 838 if (D) diagnostic = diag::note_access_constrained_by_path; 839 else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural; 840 else diagnostic = diag::note_access_constrained_by_path; 841 842 S.Diag(BS->getSourceRange().getBegin(), diagnostic) 843 << BS->getSourceRange() 844 << (BaseAccess == AS_protected) 845 << (BS->getAccessSpecifierAsWritten() == AS_none); 846 return; 847 } 848 } 849 850 llvm_unreachable("access not apparently constrained by path"); 851} 852 853static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, 854 const EffectiveContext &EC, 855 AccessTarget &Entity) { 856 const CXXRecordDecl *NamingClass = Entity.getNamingClass(); 857 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 858 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); 859 860 S.Diag(Loc, Entity.getDiag()) 861 << (Entity.getAccess() == AS_protected) 862 << (D ? D->getDeclName() : DeclarationName()) 863 << S.Context.getTypeDeclType(NamingClass) 864 << S.Context.getTypeDeclType(DeclaringClass); 865 DiagnoseAccessPath(S, EC, Entity); 866} 867 868/// Determines whether the accessed entity is accessible. Public members 869/// have been weeded out by this point. 870static AccessResult IsAccessible(Sema &S, 871 const EffectiveContext &EC, 872 AccessTarget &Entity) { 873 // Determine the actual naming class. 874 CXXRecordDecl *NamingClass = Entity.getNamingClass(); 875 while (NamingClass->isAnonymousStructOrUnion()) 876 NamingClass = cast<CXXRecordDecl>(NamingClass->getParent()); 877 NamingClass = NamingClass->getCanonicalDecl(); 878 879 AccessSpecifier UnprivilegedAccess = Entity.getAccess(); 880 assert(UnprivilegedAccess != AS_public && "public access not weeded out"); 881 882 // Before we try to recalculate access paths, try to white-list 883 // accesses which just trade in on the final step, i.e. accesses 884 // which don't require [M4] or [B4]. These are by far the most 885 // common forms of privileged access. 886 if (UnprivilegedAccess != AS_none) { 887 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) { 888 case AR_dependent: 889 // This is actually an interesting policy decision. We don't 890 // *have* to delay immediately here: we can do the full access 891 // calculation in the hope that friendship on some intermediate 892 // class will make the declaration accessible non-dependently. 893 // But that's not cheap, and odds are very good (note: assertion 894 // made without data) that the friend declaration will determine 895 // access. 896 return AR_dependent; 897 898 case AR_accessible: return AR_accessible; 899 case AR_inaccessible: break; 900 } 901 } 902 903 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext(); 904 905 // We lower member accesses to base accesses by pretending that the 906 // member is a base class of its declaring class. 907 AccessSpecifier FinalAccess; 908 909 if (Entity.isMemberAccess()) { 910 // Determine if the declaration is accessible from EC when named 911 // in its declaring class. 912 NamedDecl *Target = Entity.getTargetDecl(); 913 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); 914 915 FinalAccess = Target->getAccess(); 916 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) { 917 case AR_accessible: 918 FinalAccess = AS_public; 919 break; 920 case AR_inaccessible: break; 921 case AR_dependent: return AR_dependent; // see above 922 } 923 924 if (DeclaringClass == NamingClass) 925 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible); 926 927 Entity.suppressInstanceContext(); 928 } else { 929 FinalAccess = AS_public; 930 } 931 932 assert(Entity.getDeclaringClass() != NamingClass); 933 934 // Append the declaration's access if applicable. 935 CXXBasePaths Paths; 936 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths); 937 if (!Path) 938 return AR_dependent; 939 940 assert(Path->Access <= UnprivilegedAccess && 941 "access along best path worse than direct?"); 942 if (Path->Access == AS_public) 943 return AR_accessible; 944 return AR_inaccessible; 945} 946 947static void DelayDependentAccess(Sema &S, 948 const EffectiveContext &EC, 949 SourceLocation Loc, 950 const AccessTarget &Entity) { 951 assert(EC.isDependent() && "delaying non-dependent access"); 952 DeclContext *DC = EC.getInnerContext(); 953 assert(DC->isDependentContext() && "delaying non-dependent access"); 954 DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access, 955 Loc, 956 Entity.isMemberAccess(), 957 Entity.getAccess(), 958 Entity.getTargetDecl(), 959 Entity.getNamingClass(), 960 Entity.getBaseObjectType(), 961 Entity.getDiag()); 962} 963 964/// Checks access to an entity from the given effective context. 965static AccessResult CheckEffectiveAccess(Sema &S, 966 const EffectiveContext &EC, 967 SourceLocation Loc, 968 AccessTarget &Entity) { 969 assert(Entity.getAccess() != AS_public && "called for public access!"); 970 971 switch (IsAccessible(S, EC, Entity)) { 972 case AR_dependent: 973 DelayDependentAccess(S, EC, Loc, Entity); 974 return AR_dependent; 975 976 case AR_inaccessible: 977 if (!Entity.isQuiet()) 978 DiagnoseBadAccess(S, Loc, EC, Entity); 979 return AR_inaccessible; 980 981 case AR_accessible: 982 return AR_accessible; 983 } 984 985 // silence unnecessary warning 986 llvm_unreachable("invalid access result"); 987 return AR_accessible; 988} 989 990static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, 991 AccessTarget &Entity) { 992 // If the access path is public, it's accessible everywhere. 993 if (Entity.getAccess() == AS_public) 994 return Sema::AR_accessible; 995 996 // If we're currently parsing a top-level declaration, delay 997 // diagnostics. This is the only case where parsing a declaration 998 // can actually change our effective context for the purposes of 999 // access control. 1000 if (S.CurContext->isFileContext() && S.ParsingDeclDepth) { 1001 S.DelayedDiagnostics.push_back( 1002 Sema::DelayedDiagnostic::makeAccess(Loc, Entity)); 1003 return Sema::AR_delayed; 1004 } 1005 1006 EffectiveContext EC(S.CurContext); 1007 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) { 1008 case AR_accessible: return Sema::AR_accessible; 1009 case AR_inaccessible: return Sema::AR_inaccessible; 1010 case AR_dependent: return Sema::AR_dependent; 1011 } 1012 llvm_unreachable("falling off end"); 1013 return Sema::AR_accessible; 1014} 1015 1016void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) { 1017 // Pretend we did this from the context of the newly-parsed 1018 // declaration. 1019 EffectiveContext EC(Ctx->getDeclContext()); 1020 1021 AccessTarget Target(DD.getAccessData()); 1022 1023 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible) 1024 DD.Triggered = true; 1025} 1026 1027void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD, 1028 const MultiLevelTemplateArgumentList &TemplateArgs) { 1029 SourceLocation Loc = DD.getAccessLoc(); 1030 AccessSpecifier Access = DD.getAccess(); 1031 1032 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(), 1033 TemplateArgs); 1034 if (!NamingD) return; 1035 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(), 1036 TemplateArgs); 1037 if (!TargetD) return; 1038 1039 if (DD.isAccessToMember()) { 1040 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD); 1041 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD); 1042 QualType BaseObjectType = DD.getAccessBaseObjectType(); 1043 if (!BaseObjectType.isNull()) { 1044 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc, 1045 DeclarationName()); 1046 if (BaseObjectType.isNull()) return; 1047 } 1048 1049 AccessTarget Entity(Context, 1050 AccessTarget::Member, 1051 NamingClass, 1052 DeclAccessPair::make(TargetDecl, Access), 1053 BaseObjectType); 1054 Entity.setDiag(DD.getDiagnostic()); 1055 CheckAccess(*this, Loc, Entity); 1056 } else { 1057 AccessTarget Entity(Context, 1058 AccessTarget::Base, 1059 cast<CXXRecordDecl>(TargetD), 1060 cast<CXXRecordDecl>(NamingD), 1061 Access); 1062 Entity.setDiag(DD.getDiagnostic()); 1063 CheckAccess(*this, Loc, Entity); 1064 } 1065} 1066 1067Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, 1068 DeclAccessPair Found) { 1069 if (!getLangOptions().AccessControl || 1070 !E->getNamingClass() || 1071 Found.getAccess() == AS_public) 1072 return AR_accessible; 1073 1074 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 1075 Found, QualType()); 1076 Entity.setDiag(diag::err_access) << E->getSourceRange(); 1077 1078 return CheckAccess(*this, E->getNameLoc(), Entity); 1079} 1080 1081/// Perform access-control checking on a previously-unresolved member 1082/// access which has now been resolved to a member. 1083Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, 1084 DeclAccessPair Found) { 1085 if (!getLangOptions().AccessControl || 1086 Found.getAccess() == AS_public) 1087 return AR_accessible; 1088 1089 QualType BaseType = E->getBaseType(); 1090 if (E->isArrow()) 1091 BaseType = BaseType->getAs<PointerType>()->getPointeeType(); 1092 1093 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 1094 Found, BaseType); 1095 Entity.setDiag(diag::err_access) << E->getSourceRange(); 1096 1097 return CheckAccess(*this, E->getMemberLoc(), Entity); 1098} 1099 1100Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, 1101 CXXDestructorDecl *Dtor, 1102 const PartialDiagnostic &PDiag) { 1103 if (!getLangOptions().AccessControl) 1104 return AR_accessible; 1105 1106 // There's never a path involved when checking implicit destructor access. 1107 AccessSpecifier Access = Dtor->getAccess(); 1108 if (Access == AS_public) 1109 return AR_accessible; 1110 1111 CXXRecordDecl *NamingClass = Dtor->getParent(); 1112 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 1113 DeclAccessPair::make(Dtor, Access), 1114 QualType()); 1115 Entity.setDiag(PDiag); // TODO: avoid copy 1116 1117 return CheckAccess(*this, Loc, Entity); 1118} 1119 1120/// Checks access to a constructor. 1121Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, 1122 CXXConstructorDecl *Constructor, 1123 AccessSpecifier Access) { 1124 if (!getLangOptions().AccessControl || 1125 Access == AS_public) 1126 return AR_accessible; 1127 1128 CXXRecordDecl *NamingClass = Constructor->getParent(); 1129 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 1130 DeclAccessPair::make(Constructor, Access), 1131 QualType()); 1132 Entity.setDiag(diag::err_access_ctor); 1133 1134 return CheckAccess(*this, UseLoc, Entity); 1135} 1136 1137/// Checks direct (i.e. non-inherited) access to an arbitrary class 1138/// member. 1139Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc, 1140 NamedDecl *Target, 1141 const PartialDiagnostic &Diag) { 1142 AccessSpecifier Access = Target->getAccess(); 1143 if (!getLangOptions().AccessControl || 1144 Access == AS_public) 1145 return AR_accessible; 1146 1147 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext()); 1148 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, 1149 DeclAccessPair::make(Target, Access), 1150 QualType()); 1151 Entity.setDiag(Diag); 1152 return CheckAccess(*this, UseLoc, Entity); 1153} 1154 1155 1156/// Checks access to an overloaded operator new or delete. 1157Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, 1158 SourceRange PlacementRange, 1159 CXXRecordDecl *NamingClass, 1160 DeclAccessPair Found) { 1161 if (!getLangOptions().AccessControl || 1162 !NamingClass || 1163 Found.getAccess() == AS_public) 1164 return AR_accessible; 1165 1166 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1167 QualType()); 1168 Entity.setDiag(diag::err_access) 1169 << PlacementRange; 1170 1171 return CheckAccess(*this, OpLoc, Entity); 1172} 1173 1174/// Checks access to an overloaded member operator, including 1175/// conversion operators. 1176Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, 1177 Expr *ObjectExpr, 1178 Expr *ArgExpr, 1179 DeclAccessPair Found) { 1180 if (!getLangOptions().AccessControl || 1181 Found.getAccess() == AS_public) 1182 return AR_accessible; 1183 1184 const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>(); 1185 assert(RT && "found member operator but object expr not of record type"); 1186 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl()); 1187 1188 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1189 ObjectExpr->getType()); 1190 Entity.setDiag(diag::err_access) 1191 << ObjectExpr->getSourceRange() 1192 << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); 1193 1194 return CheckAccess(*this, OpLoc, Entity); 1195} 1196 1197Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr, 1198 DeclAccessPair Found) { 1199 if (!getLangOptions().AccessControl || 1200 Found.getAccess() == AS_none || 1201 Found.getAccess() == AS_public) 1202 return AR_accessible; 1203 1204 OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer(); 1205 NestedNameSpecifier *Qualifier = Ovl->getQualifier(); 1206 assert(Qualifier && "address of overloaded member without qualifier"); 1207 1208 CXXScopeSpec SS; 1209 SS.setScopeRep(Qualifier); 1210 SS.setRange(Ovl->getQualifierRange()); 1211 DeclContext *DC = computeDeclContext(SS); 1212 assert(DC && DC->isRecord() && "scope did not resolve to record"); 1213 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(DC); 1214 1215 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, 1216 Context.getTypeDeclType(NamingClass)); 1217 Entity.setDiag(diag::err_access) 1218 << Ovl->getSourceRange(); 1219 1220 return CheckAccess(*this, Ovl->getNameLoc(), Entity); 1221} 1222 1223/// Checks access for a hierarchy conversion. 1224/// 1225/// \param IsBaseToDerived whether this is a base-to-derived conversion (true) 1226/// or a derived-to-base conversion (false) 1227/// \param ForceCheck true if this check should be performed even if access 1228/// control is disabled; some things rely on this for semantics 1229/// \param ForceUnprivileged true if this check should proceed as if the 1230/// context had no special privileges 1231/// \param ADK controls the kind of diagnostics that are used 1232Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, 1233 QualType Base, 1234 QualType Derived, 1235 const CXXBasePath &Path, 1236 unsigned DiagID, 1237 bool ForceCheck, 1238 bool ForceUnprivileged) { 1239 if (!ForceCheck && !getLangOptions().AccessControl) 1240 return AR_accessible; 1241 1242 if (Path.Access == AS_public) 1243 return AR_accessible; 1244 1245 CXXRecordDecl *BaseD, *DerivedD; 1246 BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl()); 1247 DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl()); 1248 1249 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD, 1250 Path.Access); 1251 if (DiagID) 1252 Entity.setDiag(DiagID) << Derived << Base; 1253 1254 if (ForceUnprivileged) { 1255 switch (CheckEffectiveAccess(*this, EffectiveContext(), 1256 AccessLoc, Entity)) { 1257 case ::AR_accessible: return Sema::AR_accessible; 1258 case ::AR_inaccessible: return Sema::AR_inaccessible; 1259 case ::AR_dependent: return Sema::AR_dependent; 1260 } 1261 llvm_unreachable("unexpected result from CheckEffectiveAccess"); 1262 } 1263 return CheckAccess(*this, AccessLoc, Entity); 1264} 1265 1266/// Checks access to all the declarations in the given result set. 1267void Sema::CheckLookupAccess(const LookupResult &R) { 1268 assert(getLangOptions().AccessControl 1269 && "performing access check without access control"); 1270 assert(R.getNamingClass() && "performing access check without naming class"); 1271 1272 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { 1273 if (I.getAccess() != AS_public) { 1274 AccessTarget Entity(Context, AccessedEntity::Member, 1275 R.getNamingClass(), I.getPair(), 1276 R.getBaseObjectType()); 1277 Entity.setDiag(diag::err_access); 1278 1279 CheckAccess(*this, R.getNameLoc(), Entity); 1280 } 1281 } 1282} 1283