From 528084e553dcbebf03691467233a6e5cf19f6f2e Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 22 Jan 2019 17:59:45 +0000 Subject: [PATCH] [ASTImporter] Fix importing OperatorDelete from CXXConstructorDecl Summary: Shafik found out that importing a CXXConstructorDecl will create a translation unit that causes Clang's CodeGen to crash. The reason for that is that we don't copy the OperatorDelete from the CXXConstructorDecl when importing. This patch fixes it and adds a test case for that. Reviewers: shafik, martong, a_sidorin, a.sidorin Reviewed By: martong, a_sidorin Subscribers: rnkovacs, cfe-commits Differential Revision: https://reviews.llvm.org/D56651 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351849 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTImporter.cpp | 18 +++++++++++++++++- test/Import/destructor/Inputs/F.cpp | 3 +++ test/Import/destructor/test.cpp | 10 ++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/Import/destructor/Inputs/F.cpp create mode 100644 test/Import/destructor/test.cpp diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 6c24599103..f24a5698f5 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -3091,12 +3091,28 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { FromConstructor->isExplicit(), D->isInlineSpecified(), D->isImplicit(), D->isConstexpr())) return ToFunction; - } else if (isa(D)) { + } else if (CXXDestructorDecl *FromDtor = dyn_cast(D)) { + + auto Imp = + importSeq(const_cast(FromDtor->getOperatorDelete()), + FromDtor->getOperatorDeleteThisArg()); + + if (!Imp) + return Imp.takeError(); + + FunctionDecl *ToOperatorDelete; + Expr *ToThisArg; + std::tie(ToOperatorDelete, ToThisArg) = *Imp; + if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), cast(DC), ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), D->isImplicit())) return ToFunction; + + CXXDestructorDecl *ToDtor = cast(ToFunction); + + ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg); } else if (CXXConversionDecl *FromConversion = dyn_cast(D)) { if (GetImportedOrCreateDecl( diff --git a/test/Import/destructor/Inputs/F.cpp b/test/Import/destructor/Inputs/F.cpp new file mode 100644 index 0000000000..c33c45399d --- /dev/null +++ b/test/Import/destructor/Inputs/F.cpp @@ -0,0 +1,3 @@ +struct B { + virtual ~B() {} +}; diff --git a/test/Import/destructor/test.cpp b/test/Import/destructor/test.cpp new file mode 100644 index 0000000000..bfdee398c8 --- /dev/null +++ b/test/Import/destructor/test.cpp @@ -0,0 +1,10 @@ +// RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s + +// Triggers the deserialization of B's destructor. +B b1; + +// CHECK: CXXDestructorDecl + +// CHECK-NEXT: ~B 'void () noexcept' virtual +// CHECK-SAME: 'void () noexcept' +// CHECK-SAME: virtual -- 2.50.1