Access control for implicit destructor calls.  Diagnostic could be orders of
magnitude clearer.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95078 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 9e28b51..e49ce73 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2417,6 +2417,7 @@
                                    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);
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index ceee61d..98beb61 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -306,6 +306,31 @@
   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,
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index c6b826b..0d9918f 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -2637,6 +2637,9 @@
         Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
       }
     }
+
+    if (getLangOptions().AccessControl)
+      CheckDestructorAccess(Param->getLocation(), Param->getType());
   }
 
   return HasInvalidParm;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 745bd51..931c058 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3985,10 +3985,11 @@
 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