diff options
| -rw-r--r-- | clang/lib/Sema/Sema.h | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaAccess.cpp | 25 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 9 | ||||
| -rw-r--r-- | clang/test/CXX/class.access/p4.cpp | 29 | 
5 files changed, 63 insertions, 4 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 9e28b519ff3..e49ce733198 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index ceee61df23a..98beb610a5e 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -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, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c6b826b3270..0d9918f6e43 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -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; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 745bd513a25..931c058670b 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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 diff --git a/clang/test/CXX/class.access/p4.cpp b/clang/test/CXX/class.access/p4.cpp index 97c632a0725..83e467d9b96 100644 --- a/clang/test/CXX/class.access/p4.cpp +++ b/clang/test/CXX/class.access/p4.cpp @@ -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}} +  } +}  | 

