forked from OSchip/llvm-project
When we're trying to define an implicit virtual destructor, make sure that we have a valid delete operator.
llvm-svn: 90156
This commit is contained in:
parent
5b2f5cadbd
commit
26a807d37a
|
@ -443,8 +443,9 @@ def err_implicit_object_parameter_init : Error<
|
|||
def note_field_decl : Note<"member is declared here">;
|
||||
def note_previous_class_decl : Note<
|
||||
"%0 declared here">;
|
||||
def note_ctor_synthesized_at : Note<
|
||||
"implicit default constructor for %0 first required here">;
|
||||
def note_member_synthesized_at : Note<
|
||||
"implicit default %select{constructor|copy constructor|"
|
||||
"copy assignment operator|destructor}0 for %1 first required here">;
|
||||
def err_missing_default_ctor : Error<
|
||||
"%select{|implicit default }0constructor for %1 must explicitly initialize "
|
||||
"the %select{base class|member}2 %3 which does not have a default "
|
||||
|
|
|
@ -2135,7 +2135,7 @@ public:
|
|||
void CheckConstructor(CXXConstructorDecl *Constructor);
|
||||
QualType CheckDestructorDeclarator(Declarator &D,
|
||||
FunctionDecl::StorageClass& SC);
|
||||
void CheckDestructor(CXXDestructorDecl *Destructor);
|
||||
bool CheckDestructor(CXXDestructorDecl *Destructor);
|
||||
void CheckConversionDeclarator(Declarator &D, QualType &R,
|
||||
FunctionDecl::StorageClass& SC);
|
||||
DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
|
||||
|
|
|
@ -2367,9 +2367,9 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
|
|||
ClassDecl->addedConstructor(Context, Constructor);
|
||||
}
|
||||
|
||||
/// CheckDestructor - Checks a fully-formed destructor for
|
||||
/// well-formedness, issuing any diagnostics required.
|
||||
void Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
|
||||
/// CheckDestructor - Checks a fully-formed destructor for well-formedness,
|
||||
/// issuing any diagnostics required. Returns true on error.
|
||||
bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
|
||||
CXXRecordDecl *RD = Destructor->getParent();
|
||||
|
||||
if (Destructor->isVirtual()) {
|
||||
|
@ -2384,9 +2384,13 @@ void Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
|
|||
FunctionDecl *OperatorDelete = 0;
|
||||
DeclarationName Name =
|
||||
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
|
||||
if (!FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
|
||||
Destructor->setOperatorDelete(OperatorDelete);
|
||||
if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
|
||||
return true;
|
||||
|
||||
Destructor->setOperatorDelete(OperatorDelete);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -3071,8 +3075,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
|
|||
assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
|
||||
|
||||
if (SetBaseOrMemberInitializers(Constructor, 0, 0, true)) {
|
||||
Diag(CurrentLocation, diag::note_ctor_synthesized_at)
|
||||
<< Context.getTagDeclType(ClassDecl);
|
||||
Diag(CurrentLocation, diag::note_member_synthesized_at)
|
||||
<< CXXDefaultConstructor << Context.getTagDeclType(ClassDecl);
|
||||
Constructor->setInvalidDecl();
|
||||
} else {
|
||||
Constructor->setUsed();
|
||||
|
@ -3124,6 +3128,17 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: If CheckDestructor fails, we should emit a note about where the
|
||||
// implicit destructor was needed.
|
||||
if (CheckDestructor(Destructor)) {
|
||||
Diag(CurrentLocation, diag::note_member_synthesized_at)
|
||||
<< CXXDestructor << Context.getTagDeclType(ClassDecl);
|
||||
|
||||
Destructor->setInvalidDecl();
|
||||
return;
|
||||
}
|
||||
|
||||
Destructor->setUsed();
|
||||
}
|
||||
|
||||
|
|
|
@ -190,3 +190,15 @@ class X9 {
|
|||
void f(X9 *x9) {
|
||||
delete x9; // expected-error {{no suitable member 'operator delete' in 'X9'}}
|
||||
}
|
||||
|
||||
struct X10 {
|
||||
virtual ~X10();
|
||||
};
|
||||
|
||||
struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in 'X11'}}
|
||||
void operator delete(void*, int); // expected-note {{'operator delete' declared here}}
|
||||
};
|
||||
|
||||
void f() {
|
||||
X11 x11; // expected-note {{implicit default destructor for 'struct X11' first required here}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue