SemaAccess.cpp 66 KB

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