diff options
| author | John McCall <rjmccall@apple.com> | 2010-03-16 05:36:30 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-03-16 05:36:30 +0000 |
| commit | f857e0bbe7dfedfef956f1d9796831ec886ae300 (patch) | |
| tree | e3ef48b5003e3935563727ede48bda3ef66e406d /clang | |
| parent | 512577034667ddfa7a72b643f0c6a4ee51f32cce (diff) | |
| download | bcm5719-llvm-f857e0bbe7dfedfef956f1d9796831ec886ae300.tar.gz bcm5719-llvm-f857e0bbe7dfedfef956f1d9796831ec886ae300.zip | |
Perform access control even for the implicit destructor calls from implicit
destructor definitions. Remove some code duplication.
llvm-svn: 98611
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 39 | ||||
| -rw-r--r-- | clang/test/CXX/class.access/p4.cpp | 13 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/virtual-member-functions.cpp | 4 |
3 files changed, 14 insertions, 42 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1361318854c..1b3612d1c71 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3819,45 +3819,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, DeclContext *PreviousContext = CurContext; CurContext = Destructor; - // C++ [class.dtor] p5 - // Before the implicitly-declared default destructor for a class is - // implicitly defined, all the implicitly-declared default destructors - // for its base class and its non-static data members shall have been - // implicitly defined. - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), - E = ClassDecl->bases_end(); Base != E; ++Base) { - CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); - if (!BaseClassDecl->hasTrivialDestructor()) { - if (CXXDestructorDecl *BaseDtor = - const_cast<CXXDestructorDecl*>(BaseClassDecl->getDestructor(Context))) - MarkDeclarationReferenced(CurrentLocation, BaseDtor); - else - assert(false && - "DefineImplicitDestructor - missing dtor in a base class"); - } - } + MarkBaseAndMemberDestructorsReferenced(Destructor); - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), - E = ClassDecl->field_end(); Field != E; ++Field) { - QualType FieldType = Context.getCanonicalType((*Field)->getType()); - if (const ArrayType *Array = Context.getAsArrayType(FieldType)) - FieldType = Array->getElementType(); - if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { - CXXRecordDecl *FieldClassDecl - = cast<CXXRecordDecl>(FieldClassType->getDecl()); - if (!FieldClassDecl->hasTrivialDestructor()) { - if (CXXDestructorDecl *FieldDtor = - const_cast<CXXDestructorDecl*>( - FieldClassDecl->getDestructor(Context))) - MarkDeclarationReferenced(CurrentLocation, FieldDtor); - else - assert(false && - "DefineImplicitDestructor - missing dtor in class of a data member"); - } - } - } - // FIXME: If CheckDestructor fails, we should emit a note about where the // implicit destructor was needed. if (CheckDestructor(Destructor)) { diff --git a/clang/test/CXX/class.access/p4.cpp b/clang/test/CXX/class.access/p4.cpp index 3c7769508d3..49afcef9df4 100644 --- a/clang/test/CXX/class.access/p4.cpp +++ b/clang/test/CXX/class.access/p4.cpp @@ -112,8 +112,8 @@ namespace test3 { A local; // expected-error {{variable of type 'test3::A' has private destructor}} } - template <unsigned N> class Base { ~Base(); }; // expected-note 4 {{declared private here}} - class Base2 : virtual Base<2> { ~Base2(); }; // expected-note {{declared private here}} + template <unsigned N> class Base { ~Base(); }; // expected-note 8 {{declared private here}} + class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 2 {{declared private here}} class Base3 : virtual Base<3> { public: ~Base3(); }; // These don't cause diagnostics because we don't need the destructor. @@ -129,6 +129,15 @@ namespace test3 { { ~Derived2() {} }; + + class Derived3 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ + // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} + Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} + virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} + Base2, // expected-error {{base class 'test3::Base2' has private destructor}} + virtual Base3 + {}; + Derived3 d3; } // Conversion functions. diff --git a/clang/test/SemaTemplate/virtual-member-functions.cpp b/clang/test/SemaTemplate/virtual-member-functions.cpp index 8df808d2569..59df3c22aa1 100644 --- a/clang/test/SemaTemplate/virtual-member-functions.cpp +++ b/clang/test/SemaTemplate/virtual-member-functions.cpp @@ -36,10 +36,10 @@ struct Base { template<typename T> struct Derived : Base<T> { - virtual void foo() { } // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}} + virtual void foo() { } }; -template struct Derived<int>; +template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}} template<typename T> struct HasOutOfLineKey { |

