Windows: Fix crash on unloading of Dtor_Comdat destructors.

This commit is contained in:
Frederich Munch 2016-09-20 23:53:57 -04:00 committed by sftnight
parent b6114f10e1
commit 8644c890f4
2 changed files with 31 additions and 16 deletions

View File

@ -649,7 +649,12 @@ bool DeclUnloader::VisitRedeclarable(clang::Redeclarable<T>* 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<T>* 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<T>* 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<NamedDecl>(const_cast<Decl*>(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<VarDecl>(GD.getDecl()))
if (VD->isStaticLocal()) {
std::string functionMangledName;
GlobalDecl FDGD(cast<FunctionDecl>(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<VarDecl>(GD.getDecl())) {
if (VD->isStaticLocal()) {
std::string functionMangledName;
GlobalDecl FDGD(cast<FunctionDecl>(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);
}

View File

@ -228,7 +228,8 @@ namespace cling {
///@}
void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD) const;
void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD,
bool Mangle = true) const;
/// @name Helpers
/// @{