summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-11-30 21:24:50 +0000
committerAnders Carlsson <andersca@mac.com>2009-11-30 21:24:50 +0000
commit26a807d37a678a50d0367e0de17d78c6fc7f907e (patch)
treeb38ebb587253fbdff903886c42c0bed2b4c605d7 /clang/lib/Sema
parent5b2f5cadbd2ca9494b0cad68d1638dc26029fdf6 (diff)
downloadbcm5719-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.h2
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp29
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();
}
OpenPOWER on IntegriCloud