Windows: Fix crash on unloading of Dtor_Comdat destructors.
This commit is contained in:
parent
b6114f10e1
commit
8644c890f4
@ -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);
|
||||
}
|
||||
|
@ -228,7 +228,8 @@ namespace cling {
|
||||
|
||||
///@}
|
||||
|
||||
void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD) const;
|
||||
void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD,
|
||||
bool Mangle = true) const;
|
||||
|
||||
/// @name Helpers
|
||||
/// @{
|
||||
|
Loading…
Reference in New Issue
Block a user