From 8644c890f457ece8942c9cf51016737b5cedf79d Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Tue, 20 Sep 2016 23:53:57 -0400 Subject: [PATCH] Windows: Fix crash on unloading of Dtor_Comdat destructors. --- lib/Interpreter/DeclUnloader.cpp | 44 +++++++++++++++++++++----------- lib/Interpreter/DeclUnloader.h | 3 ++- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/lib/Interpreter/DeclUnloader.cpp b/lib/Interpreter/DeclUnloader.cpp index 35fb1c6b..9417cb36 100644 --- a/lib/Interpreter/DeclUnloader.cpp +++ b/lib/Interpreter/DeclUnloader.cpp @@ -649,7 +649,12 @@ bool DeclUnloader::VisitRedeclarable(clang::Redeclarable* R, DeclContext* DC) GD = GlobalDecl(CXXDtor, Dtor_Base); MaybeRemoveDeclFromModule(GD); GD = GlobalDecl(CXXDtor, Dtor_Comdat); +#if defined(LLVM_ON_WIN32) + // MicrosoftMangle.cpp:954 calls llvm_unreachable when mangling Dtor_Comdat + MaybeRemoveDeclFromModule(GD, false); +#else MaybeRemoveDeclFromModule(GD); +#endif bool Successful = VisitCXXMethodDecl(CXXDtor); return Successful; @@ -729,7 +734,8 @@ bool DeclUnloader::VisitRedeclarable(clang::Redeclarable* R, DeclContext* DC) return Successful; } - void DeclUnloader::MaybeRemoveDeclFromModule(GlobalDecl& GD) const { + void DeclUnloader::MaybeRemoveDeclFromModule(GlobalDecl& GD, + bool Mangle) const { if (!m_CurTransaction || !m_CurTransaction->getModule()) // syntax-only mode exit return; @@ -772,23 +778,31 @@ bool DeclUnloader::VisitRedeclarable(clang::Redeclarable* R, DeclContext* DC) // if (m_CurTransaction->getState() == Transaction::kCommitted) { std::string mangledName; - utils::Analyze::maybeMangleDeclName(GD, mangledName); + if (LLVM_UNLIKELY(!Mangle)) { + const NamedDecl* D = cast(const_cast(GD.getDecl())); + if (const IdentifierInfo *II = D->getIdentifier()) + mangledName = II->getName(); + } else + utils::Analyze::maybeMangleDeclName(GD, mangledName); - // Handle static locals. void func() { static int var; } is represented in - // the llvm::Module is a global named @func.var - if (const VarDecl* VD = dyn_cast(GD.getDecl())) - if (VD->isStaticLocal()) { - std::string functionMangledName; - GlobalDecl FDGD(cast(VD->getDeclContext())); - utils::Analyze::maybeMangleDeclName(FDGD, functionMangledName); - mangledName = functionMangledName + "." + mangledName; + if (LLVM_LIKELY(!mangledName.empty())) { + // Handle static locals. void func() { static int var; } is represented + // in the llvm::Module is a global named @func.var + if (const VarDecl* VD = dyn_cast(GD.getDecl())) { + if (VD->isStaticLocal()) { + std::string functionMangledName; + GlobalDecl FDGD(cast(VD->getDeclContext())); + utils::Analyze::maybeMangleDeclName(FDGD, functionMangledName); + mangledName = functionMangledName + "." + mangledName; + } } - llvm::Module* M = m_CurTransaction->getModule(); - GlobalValue* GV = M->getNamedValue(mangledName); - if (GV) { // May be deferred decl and thus 0 - GlobalValueEraser GVEraser(m_CodeGen); - GVEraser.EraseGlobalValue(GV); + llvm::Module* M = m_CurTransaction->getModule(); + GlobalValue* GV = M->getNamedValue(mangledName); + if (GV) { // May be deferred decl and thus 0 + GlobalValueEraser GVEraser(m_CodeGen); + GVEraser.EraseGlobalValue(GV); + } } m_CodeGen->forgetDecl(GD); } diff --git a/lib/Interpreter/DeclUnloader.h b/lib/Interpreter/DeclUnloader.h index f4a3cde3..2372ecc8 100644 --- a/lib/Interpreter/DeclUnloader.h +++ b/lib/Interpreter/DeclUnloader.h @@ -228,7 +228,8 @@ namespace cling { ///@} - void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD) const; + void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD, + bool Mangle = true) const; /// @name Helpers /// @{