Fix a code gen. crash synthesizing a destructor.
Fixes pr5660.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90283 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 4b43799..3f8babb 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1933,7 +1933,8 @@
QualType Argument);
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
- DeclarationName Name, FunctionDecl* &Operator);
+ DeclarationName Name, FunctionDecl* &Operator,
+ bool Diagnose=true);
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
@@ -2160,7 +2161,7 @@
void CheckConstructor(CXXConstructorDecl *Constructor);
QualType CheckDestructorDeclarator(Declarator &D,
FunctionDecl::StorageClass& SC);
- bool CheckDestructor(CXXDestructorDecl *Destructor);
+ bool CheckDestructor(CXXDestructorDecl *Destructor, bool Diagnose=true);
void CheckConversionDeclarator(Declarator &D, QualType &R,
FunctionDecl::StorageClass& SC);
DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index df27679..3dad051 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2171,6 +2171,7 @@
ClassDecl->addDecl(Destructor);
AddOverriddenMethods(ClassDecl, Destructor);
+ CheckDestructor(Destructor, false);
}
}
@@ -2369,7 +2370,7 @@
/// CheckDestructor - Checks a fully-formed destructor for well-formedness,
/// issuing any diagnostics required. Returns true on error.
-bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
+bool Sema::CheckDestructor(CXXDestructorDecl *Destructor, bool Diagnose) {
CXXRecordDecl *RD = Destructor->getParent();
if (Destructor->isVirtual()) {
@@ -2384,7 +2385,7 @@
FunctionDecl *OperatorDelete = 0;
DeclarationName Name =
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
- if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
+ if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete, Diagnose))
return true;
Destructor->setOperatorDelete(OperatorDelete);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 00fb65d..e626aff 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -776,7 +776,8 @@
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name,
- FunctionDecl* &Operator) {
+ FunctionDecl* &Operator,
+ bool Diagnose) {
LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
// Try to find operator delete/operator delete[] in class scope.
LookupQualifiedName(Found, RD);
@@ -796,6 +797,8 @@
// We did find operator delete/operator delete[] declarations, but
// none of them were suitable.
if (!Found.empty()) {
+ if (!Diagnose)
+ return true;
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
<< Name << RD;
diff --git a/test/CodeGenCXX/virtual-destructor-synthesis.cpp b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
new file mode 100644
index 0000000..b95218a
--- /dev/null
+++ b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+struct box {
+ virtual ~box();
+};
+
+struct pile_box : public box {
+ pile_box(box *);
+};
+
+pile_box::pile_box(box *pp)
+{
+}
+
+// CHECK: call void @_ZdlPv
+