Fix caching of std::string type.
If the Transaction that holds std::string type is unloaded LookupHelper::m_StringTy will point to invalid memory. LookupHelper::findType can return an invalid QualType causing dereference of null.
This commit is contained in:
parent
dc100ca69f
commit
8fab0d5be8
@ -48,6 +48,7 @@ namespace clang {
|
||||
class Sema;
|
||||
class SourceLocation;
|
||||
class SourceManager;
|
||||
class Type;
|
||||
class PresumedLoc;
|
||||
}
|
||||
|
||||
@ -196,6 +197,12 @@ namespace cling {
|
||||
///
|
||||
mutable std::vector<ClangInternalState*> m_StoredStates;
|
||||
|
||||
enum {
|
||||
kStdStringTransaction = 0, // Transaction known to contain std::string
|
||||
kNumTransactions
|
||||
};
|
||||
mutable const Transaction* m_CachedTrns[kNumTransactions] = {};
|
||||
|
||||
///\brief Worker function, building block for interpreter's public
|
||||
/// interfaces.
|
||||
///
|
||||
@ -690,6 +697,12 @@ namespace cling {
|
||||
///
|
||||
const Transaction* getLatestTransaction() const;
|
||||
|
||||
///\brief Returns a reference to a Transaction known to contain std::string.
|
||||
///
|
||||
const Transaction*& getStdStringTransaction() const {
|
||||
return m_CachedTrns[kStdStringTransaction];
|
||||
}
|
||||
|
||||
///\brief Compile extern "C" function and return its address.
|
||||
///
|
||||
///\param[in] name - function name
|
||||
|
@ -33,6 +33,8 @@ namespace llvm {
|
||||
|
||||
namespace cling {
|
||||
class Interpreter;
|
||||
class Transaction;
|
||||
|
||||
///\brief Reflection information query interface. The class performs lookups
|
||||
/// in the currently loaded information in the AST, using the same Parser,
|
||||
/// Sema and Preprocessor objects.
|
||||
@ -225,7 +227,6 @@ namespace cling {
|
||||
|
||||
///\brief Retrieve the QualType of `std::string`.
|
||||
const clang::Type* getStringType();
|
||||
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
@ -1275,6 +1275,14 @@ namespace cling {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear any cached transaction states.
|
||||
for (unsigned i = 0; i < kNumTransactions; ++i) {
|
||||
if (m_CachedTrns[i] == &T) {
|
||||
m_CachedTrns[i] = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (InterpreterCallbacks* callbacks = getCallbacks())
|
||||
callbacks->TransactionUnloaded(T);
|
||||
if (m_Executor) { // we also might be in fsyntax-only mode.
|
||||
|
@ -1899,8 +1899,12 @@ namespace cling {
|
||||
}
|
||||
|
||||
const Type* LookupHelper::getStringType() {
|
||||
if (!m_StringTy)
|
||||
m_StringTy = findType("std::string", WithDiagnostics).getTypePtr();
|
||||
const Transaction*& Cache = m_Interpreter->getStdStringTransaction();
|
||||
if (!Cache || !m_StringTy) {
|
||||
QualType Qt = findType("std::string", WithDiagnostics);
|
||||
if ((m_StringTy = Qt.isNull() ? nullptr : Qt.getTypePtr()))
|
||||
Cache = m_Interpreter->getLatestTransaction();
|
||||
}
|
||||
return m_StringTy;
|
||||
}
|
||||
|
||||
|
@ -776,9 +776,11 @@ static std::string printUnpackedClingValue(const Value &V) {
|
||||
} else if (clang::CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl()) {
|
||||
if (CXXRD->isLambda())
|
||||
return printAddress(V.getPtr(), '@');
|
||||
LookupHelper& LH= V.getInterpreter()->getLookupHelper();
|
||||
if (C.hasSameType(CXXRD->getTypeForDecl(), LH.getStringType()))
|
||||
return executePrintValue<std::string>(V, *(std::string*)V.getPtr());
|
||||
if (const clang::Type* StrTy =
|
||||
V.getInterpreter()->getLookupHelper().getStringType()) {
|
||||
if (C.hasSameType(CXXRD->getTypeForDecl(), StrTy))
|
||||
return executePrintValue<std::string>(V, *(std::string*)V.getPtr());
|
||||
}
|
||||
} else if (const clang::BuiltinType *BT
|
||||
= llvm::dyn_cast<clang::BuiltinType>(Td.getCanonicalType().getTypePtr())) {
|
||||
switch (BT->getKind()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user