diff options
author | Anders Carlsson <andersca@mac.com> | 2009-11-30 21:24:50 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-11-30 21:24:50 +0000 |
commit | 26a807d37a678a50d0367e0de17d78c6fc7f907e (patch) | |
tree | b38ebb587253fbdff903886c42c0bed2b4c605d7 /clang/lib/Sema | |
parent | 5b2f5cadbd2ca9494b0cad68d1638dc26029fdf6 (diff) | |
download | bcm5719-llvm-26a807d37a678a50d0367e0de17d78c6fc7f907e.tar.gz bcm5719-llvm-26a807d37a678a50d0367e0de17d78c6fc7f907e.zip |
When we're trying to define an implicit virtual destructor, make sure that we have a valid delete operator.
llvm-svn: 90156
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 29 |
2 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 5577cbd7d74..232b502bf9c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 34ab7429588..f161cb5546a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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(); } |