diff options
| author | John McCall <rjmccall@apple.com> | 2010-03-30 21:47:33 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-03-30 21:47:33 +0000 |
| commit | 16df1e59f2bb77de9ccdbc36262679d84f8a7d54 (patch) | |
| tree | ee052fb68e2d926668439e8d67cb88dd5c8e481d /clang/lib/Sema/SemaAccess.cpp | |
| parent | cf35648ebe0b23c3a0eb0917f1dd21e5b3693e07 (diff) | |
| download | bcm5719-llvm-16df1e59f2bb77de9ccdbc36262679d84f8a7d54.tar.gz bcm5719-llvm-16df1e59f2bb77de9ccdbc36262679d84f8a7d54.zip | |
Propagate the "found declaration" (i.e. the using declaration instead of
the underlying/instantiated decl) through a lot of API, including "intermediate"
MemberExprs required for (e.g.) template instantiation. This is necessary
because of the access semantics of member accesses to using declarations:
only the base class *containing the using decl* need be accessible from the
naming class.
This allows us to complete an access-controlled selfhost, if there are no
recent regressions.
llvm-svn: 99936
Diffstat (limited to 'clang/lib/Sema/SemaAccess.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaAccess.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index e7ea2041370..e356c52a684 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -907,6 +907,31 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, return CheckAccess(*this, OpLoc, Entity); } +Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr, + DeclAccessPair Found) { + if (!getLangOptions().AccessControl || + Found.getAccess() == AS_public) + return AR_accessible; + + OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer(); + NestedNameSpecifier *Qualifier = Ovl->getQualifier(); + assert(Qualifier && "address of overloaded member without qualifier"); + + CXXScopeSpec SS; + SS.setScopeRep(Qualifier); + SS.setRange(Ovl->getQualifierRange()); + DeclContext *DC = computeDeclContext(SS); + assert(DC && DC->isRecord() && "scope did not resolve to record"); + CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(DC); + + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, Found); + Entity.setDiag(diag::err_access) + << Ovl->getSourceRange(); + + return CheckAccess(*this, Ovl->getNameLoc(), Entity); +} + + /// Checks access for a hierarchy conversion. /// /// \param IsBaseToDerived whether this is a base-to-derived conversion (true) |

