Fix for Interpreter hanging on to states that can refer to a deleted llvm::Module.
This commit is contained in:
parent
f057cf9b0c
commit
4dd1ce8e56
@ -81,6 +81,10 @@ namespace cling {
|
||||
const char* type = nullptr, bool verbose = false,
|
||||
const llvm::SmallVectorImpl<llvm::StringRef>* ignores = 0) const;
|
||||
|
||||
///\brief Return the llvm::Module this state is bound too.
|
||||
///
|
||||
const llvm::Module* getModule() const { return m_Module; }
|
||||
|
||||
static void printLookupTables(llvm::raw_ostream& Out, const clang::ASTContext& C);
|
||||
static void printIncludedFiles(llvm::raw_ostream& Out,
|
||||
const clang::SourceManager& SM);
|
||||
|
@ -314,10 +314,14 @@ namespace cling {
|
||||
}
|
||||
|
||||
Interpreter::~Interpreter() {
|
||||
if (m_Executor)
|
||||
m_Executor->shuttingDown();
|
||||
// Do this first so m_StoredStates will be ignored if Interpreter::unload
|
||||
// is called later on.
|
||||
for (size_t i = 0, e = m_StoredStates.size(); i != e; ++i)
|
||||
delete m_StoredStates[i];
|
||||
m_StoredStates.clear();
|
||||
|
||||
if (m_Executor)
|
||||
m_Executor->shuttingDown();
|
||||
|
||||
if (CompilerInstance* CI = getCIOrNull())
|
||||
getCI()->getDiagnostics().getClient()->EndSourceFile();
|
||||
@ -1177,6 +1181,29 @@ namespace cling {
|
||||
}
|
||||
|
||||
void Interpreter::unload(Transaction& T) {
|
||||
// Clear any stored states that reference the llvm::Module.
|
||||
// Do it first in case
|
||||
if (!m_StoredStates.empty()) {
|
||||
const llvm::Module* const module = T.getModule();
|
||||
std::vector<unsigned> badStates;
|
||||
for (unsigned i = 0, N = m_StoredStates.size(); i < N; ++i) {
|
||||
if (m_StoredStates[i]->getModule() == module) {
|
||||
badStates.push_back(i);
|
||||
if (m_Opts.Verbose()) {
|
||||
cling::errs() << "Unloading Transaction forced state '"
|
||||
<< m_StoredStates[i]->getName()
|
||||
<< "' to be destroyed\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pop off the back so as not to recompute index.
|
||||
// Should the user be warned in verbose mode?
|
||||
for (std::vector<unsigned>::reverse_iterator it = badStates.rbegin(),
|
||||
e = badStates.rend(); it != e; ++it) {
|
||||
m_StoredStates.erase(m_StoredStates.begin()+(*it));
|
||||
}
|
||||
}
|
||||
|
||||
if (InterpreterCallbacks* callbacks = getCallbacks())
|
||||
callbacks->TransactionUnloaded(T);
|
||||
if (m_Executor) { // we also might be in fsyntax-only mode.
|
||||
|
19
test/ErrorRecovery/StoredState.C
Normal file
19
test/ErrorRecovery/StoredState.C
Normal file
@ -0,0 +1,19 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
//
|
||||
// This file is dual-licensed: you can choose to license it under the University
|
||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
||||
// LICENSE.TXT for details.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// RUN: cat %s | %cling -v -Xclang -verify 2>&1 | FileCheck %s
|
||||
|
||||
int i = 0;
|
||||
.storeState "A"
|
||||
|
||||
.undo
|
||||
// CHECK: Unloading Transaction forced state 'A' to be destroyed
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
.q
|
Loading…
Reference in New Issue
Block a user