[cfe-commits] r76317 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaAccess.cpp lib/Sema/SemaType.cpp test/SemaCXX/exception-spec.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Sat Jul 18 07:32:46 PDT 2009
Author: cornedbee
Date: Sat Jul 18 09:32:15 2009
New Revision: 76317
URL: http://llvm.org/viewvc/llvm-project?rev=76317&view=rev
Log:
Enhance testing of overriding exception specs for inaccessible base exceptions.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaAccess.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaCXX/exception-spec.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=76317&r1=76316&r2=76317&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Jul 18 09:32:15 2009
@@ -1989,17 +1989,21 @@
//===--------------------------------------------------------------------===//
// C++ Access Control
//
-
+
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
NamedDecl *PrevMemberDecl,
AccessSpecifier LexicalAS);
-
- bool CheckBaseClassAccess(QualType Derived, QualType Base,
+
+ const CXXBaseSpecifier *FindInaccessibleBase(QualType Derived, QualType Base,
+ BasePaths &Paths,
+ bool NoPrivileges = false);
+
+ bool CheckBaseClassAccess(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
BasePaths& Paths, SourceLocation AccessLoc,
DeclarationName Name);
-
-
+
+
enum AbstractDiagSelID {
AbstractNone = -1,
AbstractReturnType,
Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=76317&r1=76316&r2=76317&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Sat Jul 18 09:32:15 2009
@@ -43,36 +43,34 @@
return false;
}
-/// CheckBaseClassAccess - Check that a derived class can access its base class
-/// and report an error if it can't. [class.access.base]
-bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
- unsigned InaccessibleBaseID,
- BasePaths& Paths, SourceLocation AccessLoc,
- DeclarationName Name) {
+/// Find a class on the derivation path between Derived and Base that is
+/// inaccessible. If @p NoPrivileges is true, special access rights (members
+/// and friends) are not considered.
+const CXXBaseSpecifier *Sema::FindInaccessibleBase(
+ QualType Derived, QualType Base, BasePaths &Paths, bool NoPrivileges)
+{
Base = Context.getCanonicalType(Base).getUnqualifiedType();
assert(!Paths.isAmbiguous(Base) &&
"Can't check base class access if set of paths is ambiguous");
assert(Paths.isRecordingPaths() &&
"Can't check base class access without recorded paths");
-
- if (!getLangOptions().AccessControl)
- return false;
-
- const CXXBaseSpecifier *InacessibleBase = 0;
- const CXXRecordDecl* CurrentClassDecl = 0;
+
+ const CXXBaseSpecifier *InaccessibleBase = 0;
+
+ const CXXRecordDecl *CurrentClassDecl = 0;
if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(getCurFunctionDecl()))
CurrentClassDecl = MD->getParent();
- for (BasePaths::paths_iterator Path = Paths.begin(), PathsEnd = Paths.end();
+ for (BasePaths::paths_iterator Path = Paths.begin(), PathsEnd = Paths.end();
Path != PathsEnd; ++Path) {
-
+
bool FoundInaccessibleBase = false;
-
- for (BasePath::const_iterator Element = Path->begin(),
+
+ for (BasePath::const_iterator Element = Path->begin(),
ElementEnd = Path->end(); Element != ElementEnd; ++Element) {
const CXXBaseSpecifier *Base = Element->Base;
-
+
switch (Base->getAccessSpecifier()) {
default:
assert(0 && "invalid access specifier");
@@ -81,44 +79,59 @@
break;
case AS_private:
// FIXME: Check if the current function/class is a friend.
- if (CurrentClassDecl != Element->Class)
+ if (NoPrivileges || CurrentClassDecl != Element->Class)
FoundInaccessibleBase = true;
break;
- case AS_protected:
+ case AS_protected:
// FIXME: Implement
break;
}
-
+
if (FoundInaccessibleBase) {
- InacessibleBase = Base;
+ InaccessibleBase = Base;
break;
}
}
-
+
if (!FoundInaccessibleBase) {
// We found a path to the base, our work here is done.
- InacessibleBase = 0;
- break;
+ return 0;
}
}
- if (InacessibleBase) {
+ assert(InaccessibleBase && "no path found, but no inaccessible base");
+ return InaccessibleBase;
+}
+
+/// CheckBaseClassAccess - Check that a derived class can access its base class
+/// and report an error if it can't. [class.access.base]
+bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
+ unsigned InaccessibleBaseID,
+ BasePaths &Paths, SourceLocation AccessLoc,
+ DeclarationName Name) {
+
+ if (!getLangOptions().AccessControl)
+ return false;
+ const CXXBaseSpecifier *InaccessibleBase = FindInaccessibleBase(
+ Derived, Base, Paths);
+
+ if (InaccessibleBase) {
Diag(AccessLoc, InaccessibleBaseID)
<< Derived << Base << Name;
- AccessSpecifier AS = InacessibleBase->getAccessSpecifierAsWritten();
-
+ AccessSpecifier AS = InaccessibleBase->getAccessSpecifierAsWritten();
+
// If there's no written access specifier, then the inheritance specifier
// is implicitly private.
if (AS == AS_none)
- Diag(InacessibleBase->getSourceRange().getBegin(),
+ Diag(InaccessibleBase->getSourceRange().getBegin(),
diag::note_inheritance_implicitly_private_here);
else
- Diag(InacessibleBase->getSourceRange().getBegin(),
+ Diag(InaccessibleBase->getSourceRange().getBegin(),
diag::note_inheritance_specifier_here) << AS;
return true;
}
-
+
return false;
}
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=76317&r1=76316&r2=76317&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat Jul 18 09:32:15 2009
@@ -1294,7 +1294,7 @@
bool SubIsClass = CanonicalSubT->isRecordType();
CanonicalSubT.setCVRQualifiers(0);
- BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
+ BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
bool Contained = false;
@@ -1332,7 +1332,8 @@
if (Paths.isAmbiguous(CanonicalSuperT))
continue;
- // FIXME: Check base access. Don't forget to enable path recording.
+ if (FindInaccessibleBase(CanonicalSubT, CanonicalSuperT, Paths, true))
+ continue;
Contained = true;
break;
Modified: cfe/trunk/test/SemaCXX/exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exception-spec.cpp?rev=76317&r1=76316&r2=76317&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/exception-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/exception-spec.cpp Sat Jul 18 09:32:15 2009
@@ -78,6 +78,10 @@
{
};
+struct P : private A
+{
+};
+
struct Base
{
virtual void f1() throw();
@@ -94,6 +98,7 @@
virtual void g2() throw(int); // expected-note {{overridden virtual function is here}}
virtual void g3() throw(A); // expected-note {{overridden virtual function is here}}
virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}}
+ virtual void g5() throw(A); // expected-note {{overridden virtual function is here}}
};
struct Derived : Base
{
@@ -111,4 +116,5 @@
virtual void g2(); // expected-error {{exception specification of overriding function is more lax}}
virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}}
virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}}
};
More information about the cfe-commits
mailing list