Yup. Both patched was cleaned and reattached.
-Stepan.
Nikola Smiljanic wrote:
Hi Stepan,
I can confirm that both patches fix the issue, but I'm in no position
to review the implementation. I've added John McCall to CC as he seems
to be the owner of the Access code.
However I do have few nits:
There are two unnecessary spaces at the end of your change in SemaDeclCXX.cpp.
AccessTarget parameter of CheckAccessNow function is not aligned
properly, you should indent it by two spaces.
The && in the assert condition inside CheckLookupAccessNow should be
on the previous line, the same probably goes for assert in
CheckLookupAccess (I'm guessing that you copied code from there :).
Thanks for getting back to this.
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h (revision 161486)
+++ include/clang/Sema/Sema.h (working copy)
@@ -4444,6 +4444,7 @@
bool ForceCheck = false,
bool ForceUnprivileged = false);
void CheckLookupAccess(const LookupResult &R);
+ void CheckLookupAccessNow(const LookupResult &R);
bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
AccessSpecifier access,
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp (revision 161486)
+++ lib/Sema/SemaDeclCXX.cpp (working copy)
@@ -10306,6 +10306,10 @@
}
}
+ if (Previous.getResultKind() == LookupResult::Found &&
+ Previous.getFoundDecl()->isCXXClassMember())
+ CheckLookupAccessNow(Previous);
+
// FIXME: This is an egregious hack to cope with cases where the scope stack
// does not contain the declaration context, i.e., in an out-of-line
// definition of a class.
Index: lib/Sema/SemaAccess.cpp
===================================================================
--- lib/Sema/SemaAccess.cpp (revision 161486)
+++ lib/Sema/SemaAccess.cpp (working copy)
@@ -1418,6 +1418,24 @@
llvm_unreachable("falling off end");
}
+/// CheckAccessNow - does the same as CheckAccess, but doesn't perform
+/// delayed diagnostics. It is supposed that user knows that diagnostics
+/// shouldn't be delayed.
+static Sema::AccessResult CheckAccessNow(Sema &S, SourceLocation Loc,
+ AccessTarget &Entity) {
+ // If the access path is public, it's accessible everywhere.
+ if (Entity.getAccess() == AS_public)
+ return Sema::AR_accessible;
+
+ EffectiveContext EC(S.CurContext);
+ switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
+ case AR_accessible: return Sema::AR_accessible;
+ case AR_inaccessible: return Sema::AR_inaccessible;
+ case AR_dependent: return Sema::AR_dependent;
+ }
+ llvm_unreachable("falling off end");
+}
+
void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
// Access control for names used in the declarations of functions
// and function templates should normally be evaluated in the context
@@ -1768,6 +1786,23 @@
}
}
+/// Checks access to all the declarations in the given result set.
+void Sema::CheckLookupAccessNow(const LookupResult &R) {
+ assert(getLangOpts().AccessControl &&
+ "performing access check without access control");
+ assert(R.getNamingClass() && "performing access check without naming class");
+
+ for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+ if (I.getAccess() != AS_public) {
+ AccessTarget Entity(Context, AccessedEntity::Member,
+ R.getNamingClass(), I.getPair(),
+ R.getBaseObjectType());
+ Entity.setDiag(diag::err_access);
+ CheckAccessNow(*this, R.getNameLoc(), Entity);
+ }
+ }
+}
+
/// Checks access to Decl from the given class. The check will take access
/// specifiers into account, but no member access expressions and such.
///
Index: include/clang/Sema/DelayedDiagnostic.h
===================================================================
--- include/clang/Sema/DelayedDiagnostic.h (revision 161486)
+++ include/clang/Sema/DelayedDiagnostic.h (working copy)
@@ -44,10 +44,13 @@
MemberNonce _,
CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl,
- QualType BaseObjectType)
+ QualType BaseObjectType,
+ DeclContext *FromContext = 0)
: Access(FoundDecl.getAccess()), IsMember(true),
Target(FoundDecl.getDecl()), NamingClass(NamingClass),
- BaseObjectType(BaseObjectType), Diag(0, Allocator) {
+ BaseObjectType(BaseObjectType),
+ FromContext(FromContext),
+ Diag(0, Allocator) {
}
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
@@ -58,6 +61,7 @@
: Access(Access), IsMember(false),
Target(BaseClass),
NamingClass(DerivedClass),
+ FromContext(0),
Diag(0, Allocator) {
}
@@ -79,6 +83,10 @@
/// an instance member.
QualType getBaseObjectType() const { return BaseObjectType; }
+ /// Retrieves the specified DeclarationContext from which
+ /// we want to access the target.
+ DeclContext *getFromContext() const { return FromContext; }
+
/// Sets a diagnostic to be performed. The diagnostic is given
/// four (additional) arguments:
/// %0 - 0 if the entity was private, 1 if protected
@@ -105,6 +113,7 @@
NamedDecl *Target;
CXXRecordDecl *NamingClass;
QualType BaseObjectType;
+ DeclContext *FromContext;
PartialDiagnostic Diag;
};
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h (revision 161486)
+++ include/clang/Sema/Sema.h (working copy)
@@ -4443,7 +4443,7 @@
unsigned DiagID,
bool ForceCheck = false,
bool ForceUnprivileged = false);
- void CheckLookupAccess(const LookupResult &R);
+ void CheckLookupAccess(const LookupResult &R, bool UseCurContext = false);
bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
AccessSpecifier access,
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp (revision 161486)
+++ lib/Sema/SemaDeclCXX.cpp (working copy)
@@ -10306,6 +10306,10 @@
}
}
+ if (Previous.getResultKind() == LookupResult::Found &&
+ Previous.getFoundDecl()->isCXXClassMember())
+ CheckLookupAccess(Previous, true);
+
// FIXME: This is an egregious hack to cope with cases where the scope stack
// does not contain the declaration context, i.e., in an out-of-line
// definition of a class.
Index: lib/Sema/SemaAccess.cpp
===================================================================
--- lib/Sema/SemaAccess.cpp (revision 161486)
+++ lib/Sema/SemaAccess.cpp (working copy)
@@ -151,9 +151,10 @@
MemberNonce _,
CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl,
- QualType BaseObjectType)
+ QualType BaseObjectType,
+ DeclContext *FromContext = 0)
: AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
- FoundDecl, BaseObjectType) {
+ FoundDecl, BaseObjectType, FromContext) {
initialize();
}
@@ -1424,12 +1425,15 @@
// of the declaration, just in case it's a friend of something.
// However, this does not apply to local extern declarations.
- DeclContext *DC = decl->getDeclContext();
- if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
- if (!DC->isFunctionOrMethod()) DC = fn;
- } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
- // Never a local declaration.
- DC = fnt->getTemplatedDecl();
+ DeclContext *DC = DD.getAccessData().getFromContext();
+ if (!DC) {
+ DC = decl->getDeclContext();
+ if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
+ if (!DC->isFunctionOrMethod()) DC = fn;
+ } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
+ // Never a local declaration.
+ DC = fnt->getTemplatedDecl();
+ }
}
EffectiveContext EC(DC);
@@ -1752,7 +1756,7 @@
}
/// Checks access to all the declarations in the given result set.
-void Sema::CheckLookupAccess(const LookupResult &R) {
+void Sema::CheckLookupAccess(const LookupResult &R, bool UseCurContext) {
assert(getLangOpts().AccessControl
&& "performing access check without access control");
assert(R.getNamingClass() && "performing access check without naming class");
@@ -1761,7 +1765,8 @@
if (I.getAccess() != AS_public) {
AccessTarget Entity(Context, AccessedEntity::Member,
R.getNamingClass(), I.getPair(),
- R.getBaseObjectType());
+ R.getBaseObjectType(),
+ UseCurContext ? CurContext : 0);
Entity.setDiag(diag::err_access);
CheckAccess(*this, R.getNameLoc(), Entity);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits