[cfe-commits] r162616 - in /cfe/trunk: lib/Sema/SemaAccess.cpp test/CXX/class.access/class.friend/p1.cpp test/CXX/class.access/class.protected/p1.cpp

John McCall rjmccall at apple.com
Fri Aug 24 15:54:02 PDT 2012


Author: rjmccall
Date: Fri Aug 24 17:54:02 2012
New Revision: 162616

URL: http://llvm.org/viewvc/llvm-project?rev=162616&view=rev
Log:
When computing the effective context for access control,
make sure we walk up the DC chain for the current context,
rather than allowing ourselves to get switched over to the
canonical DC chain.  Fixes PR13642.

Modified:
    cfe/trunk/lib/Sema/SemaAccess.cpp
    cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
    cfe/trunk/test/CXX/class.access/class.protected/p1.cpp

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=162616&r1=162615&r2=162616&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Fri Aug 24 17:54:02 2012
@@ -97,14 +97,19 @@
     // functions (which can gain privileges through friendship), but we
     // take that as an oversight.
     while (true) {
+      // We want to add canonical declarations to the EC lists for
+      // simplicity of checking, but we need to walk up through the
+      // actual current DC chain.  Otherwise, something like a local
+      // extern or friend which happens to be the canonical
+      // declaration will really mess us up.
+
       if (isa<CXXRecordDecl>(DC)) {
-        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
-        Records.push_back(Record);
+        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
+        Records.push_back(Record->getCanonicalDecl());
         DC = Record->getDeclContext();
       } else if (isa<FunctionDecl>(DC)) {
-        FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl();
-        Functions.push_back(Function);
-        
+        FunctionDecl *Function = cast<FunctionDecl>(DC);
+        Functions.push_back(Function->getCanonicalDecl());
         if (Function->getFriendObjectKind())
           DC = Function->getLexicalDeclContext();
         else

Modified: cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p1.cpp?rev=162616&r1=162615&r2=162616&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/class.friend/p1.cpp (original)
+++ cfe/trunk/test/CXX/class.access/class.friend/p1.cpp Fri Aug 24 17:54:02 2012
@@ -356,3 +356,19 @@
     }
   };
 }
+
+// PR13642.  When computing the effective context, we were walking up
+// the DC chain for the canonical decl, which is unfortunate if that's
+// (e.g.) a friend declaration.
+namespace test14 {
+  class A {
+    class B { // expected-note {{implicitly declared private here}}
+      static int i;
+      friend void c();
+    };
+  };
+
+  void c() {
+    A::B::i = 5; // expected-error {{'B' is a private member of 'test14::A'}}
+  }
+}

Modified: cfe/trunk/test/CXX/class.access/class.protected/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.protected/p1.cpp?rev=162616&r1=162615&r2=162616&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/class.protected/p1.cpp (original)
+++ cfe/trunk/test/CXX/class.access/class.protected/p1.cpp Fri Aug 24 17:54:02 2012
@@ -423,7 +423,7 @@
 // This friendship is not considered because a public member of A is
 // inaccessible in C.
 namespace test13 {
-  class A { protected: int foo(); }; // expected-note {{can only access this member on an object of type}}
+  class A { protected: int foo(); }; // expected-note {{declared protected here}}
   class B : private virtual A {};
   class C : private B { friend void test(); };
   class D : public virtual A {};





More information about the cfe-commits mailing list