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
+