[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