]> granicus.if.org Git - clang/commitdiff
Access control for implicit destructor calls. Diagnostic could be orders of
authorJohn McCall <rjmccall@apple.com>
Tue, 2 Feb 2010 08:45:54 +0000 (08:45 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 2 Feb 2010 08:45:54 +0000 (08:45 +0000)
magnitude clearer.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95078 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaAccess.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaDeclCXX.cpp
test/CXX/class.access/p4.cpp

index 9e28b519ff36e7105d0a88cec5a78c69d4ba71d8..e49ce7331987c0f004a955ae0c3c68ff8a0e6612 100644 (file)
@@ -2417,6 +2417,7 @@ public:
                                    AccessSpecifier Access);
   bool CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D,
                               AccessSpecifier Access);
+  bool CheckDestructorAccess(SourceLocation Loc, QualType T);
   bool CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
                                  NamedDecl *D, AccessSpecifier Access);
   bool CheckAccess(const LookupResult &R, NamedDecl *D, AccessSpecifier Access);
index ceee61df23a1e85241ba7458a68cf3630bc3a671..98beb610a5ea8f89aead5017e46c4297f51c147f 100644 (file)
@@ -306,6 +306,31 @@ bool Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
   return false;
 }
 
+bool Sema::CheckDestructorAccess(SourceLocation Loc,
+                                 QualType T) {
+  if (!getLangOptions().AccessControl)
+    return false;
+
+  const RecordType *Record = T->getAs<RecordType>();
+  if (!Record)
+    return false;
+
+  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Record->getDecl());
+  CXXDestructorDecl *Dtor = NamingClass->getDestructor(Context);
+
+  AccessSpecifier Access = Dtor->getAccess();
+  if (Access == AS_public)
+    return false;
+
+  LookupResult R(*this, Dtor->getDeclName(), Loc, LookupOrdinaryName);
+  R.suppressDiagnostics();
+
+  R.setNamingClass(NamingClass);
+  return CheckAccess(R, Dtor, Access);
+
+  // FIXME: protected check
+}
+
 /// Checks access to a constructor.
 bool Sema::CheckConstructorAccess(SourceLocation UseLoc,
                                   CXXConstructorDecl *Constructor,
index c6b826b32703de1e62259773eb383c23c407f2a3..0d9918f6e43fb0de2a0b41cb4295094ad530aab9 100644 (file)
@@ -2637,6 +2637,9 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
         Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
       }
     }
+
+    if (getLangOptions().AccessControl)
+      CheckDestructorAccess(Param->getLocation(), Param->getType());
   }
 
   return HasInvalidParm;
index 745bd513a25a7f69ecbe871481ecb76698db1b34..931c058670bbb05adcf38c8584b4e65dc9ba8321 100644 (file)
@@ -3985,10 +3985,11 @@ bool Sema::InitializeVarWithConstructor(VarDecl *VD,
 void Sema::FinalizeVarWithDestructor(VarDecl *VD, QualType DeclInitType) {
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(
                                   DeclInitType->getAs<RecordType>()->getDecl());
-  if (!ClassDecl->hasTrivialDestructor())
-    if (CXXDestructorDecl *Destructor =
-        const_cast<CXXDestructorDecl*>(ClassDecl->getDestructor(Context)))
-      MarkDeclarationReferenced(VD->getLocation(), Destructor);
+  if (!ClassDecl->hasTrivialDestructor()) {
+    CXXDestructorDecl *Destructor = ClassDecl->getDestructor(Context);
+    MarkDeclarationReferenced(VD->getLocation(), Destructor);
+    CheckDestructorAccess(VD->getLocation(), VD->getType());
+  }
 }
 
 /// AddCXXDirectInitializerToDecl - This action is called immediately after
index 97c632a07251e07d1b8d66af38d7b67db2ebd6e2..83e467d9b963dd685c3728cb4174c1e5b350853e 100644 (file)
@@ -83,3 +83,32 @@ namespace test1 {
     ca(priv); // expected-error {{access to private member}}
   }
 }
+
+// Implicit constructor calls.
+namespace test2 {
+  class A {
+  private:
+    A(); // expected-note {{declared private here}}
+
+    static A foo;
+  };
+
+  A a; // expected-error {{access to private member}}
+  A A::foo; // okay
+}
+
+// Implicit destructor calls.
+namespace test3 {
+  class A{
+  private:
+    ~A(); // expected-note 3 {{declared private here}}
+    static A foo;
+  };
+
+  A a; // expected-error {{access to private member}}
+  A A::foo;
+
+  void foo(A param) { // expected-error {{access to private member}}
+    A local; // expected-error {{access to private member}}
+  }
+}