зеркало из https://github.com/microsoft/clang-1.git
Perform access control even for the implicit destructor calls from implicit
destructor definitions. Remove some code duplication. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98611 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
58e6f34e4d
Коммит
6c790eac94
|
@ -3819,44 +3819,7 @@ 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");
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
MarkBaseAndMemberDestructorsReferenced(Destructor);
|
||||
|
||||
// FIXME: If CheckDestructor fails, we should emit a note about where the
|
||||
// implicit destructor was needed.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче