Skip to content

Commit 10e40ba

Browse files
committed
Fix crash when dumping an un-evaluated cling::Value and standardize string for undefined values.
1 parent 7546af7 commit 10e40ba

File tree

5 files changed

+24
-10
lines changed

5 files changed

+24
-10
lines changed

include/cling/Interpreter/RuntimePrintValue.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,20 @@
2121
namespace cling {
2222

2323
class Value;
24+
namespace valuePrinterInternal {
25+
extern const char* const kEmptyCollection;
26+
extern const char* const kUndefined;
27+
}
2428

2529
// General fallback - prints the address
2630
std::string printValue(const void *ptr);
2731

2832
// Fallback for e.g. vector<bool>'s bit iterator:
2933
template <class T,
30-
class = typename std::enable_if<!std::is_pointer<T>::value>::type>
31-
std::string printValue(const T& val) { return "{not representable}"; }
34+
class = typename std::enable_if<!std::is_pointer<T>::value>::type>
35+
std::string printValue(const T& val) {
36+
return valuePrinterInternal::kUndefined;
37+
}
3238

3339
// void pointer
3440
std::string printValue(const void **ptr);
@@ -114,10 +120,6 @@ namespace cling {
114120
// cling::Value
115121
std::string printValue(const Value *value);
116122

117-
namespace valuePrinterInternal {
118-
extern const char* const kEmptyCollection;
119-
}
120-
121123
// Collections internal
122124
namespace collectionPrinterInternal {
123125

lib/Interpreter/Value.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,15 @@ namespace cling {
231231
namespace valuePrinterInternal {
232232
std::string printTypeInternal(const Value& V);
233233
std::string printValueInternal(const Value& V);
234+
extern const char* const kInvalid;
234235
} // end namespace valuePrinterInternal
235236

236237
void Value::print(llvm::raw_ostream& Out, bool Escape) const {
238+
if (!m_Interpreter) {
239+
Out << valuePrinterInternal::kInvalid << "\n";
240+
return;
241+
}
242+
237243
// Save the default type string representation so output can occur as one
238244
// operation (calling printValueInternal below may write to stderr).
239245
const std::string Type = valuePrinterInternal::printTypeInternal(*this);

lib/Interpreter/ValuePrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ extern "C" void cling_PrintValue(void * /*cling::Value**/ V) {
5555
namespace cling {
5656
namespace valuePrinterInternal {
5757
extern const char* const kEmptyCollection = "{}";
58+
extern const char* const kUndefined = "<<<undefined>>>";
59+
extern const char* const kInvalid = "<<<invalid>>>";
5860
}
5961
}
6062

@@ -602,7 +604,7 @@ static std::string callPrintValue(const Value& V, const void* Val) {
602604
"Could not execute cling::printValue with '%0'");
603605
Diag.Report(Interp->getSourceLocation(), ID) << getTypeString(V);
604606

605-
return "ERROR in cling's callPrintValue(): missing value string.";
607+
return valuePrinterInternal::kUndefined;
606608
}
607609

608610
template <typename T>
@@ -847,18 +849,20 @@ namespace cling {
847849
}
848850
strm << "]";
849851
} else
850-
strm << "<<<invalid>>> " << printAddress(value, '@');
852+
strm << valuePrinterInternal::kInvalid << ' ' << printAddress(value, '@');
851853

852854
return strm.str();
853855
}
854856

855857
namespace valuePrinterInternal {
856858

857859
std::string printTypeInternal(const Value &V) {
860+
assert(V.getInterpreter() && "Invalid cling::Value");
858861
return printQualType(V.getASTContext(), V.getType());
859862
}
860863

861864
std::string printValueInternal(const Value &V) {
865+
assert(V.getInterpreter() && "Invalid cling::Value");
862866
static bool includedRuntimePrintValue = false; // initialized only once as a static function variable
863867
// Include "RuntimePrintValue.h" only on the first printing.
864868
// This keeps the interpreter lightweight and reduces the startup time.

test/Interfaces/evaluate.C

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
cling::Value V;
1616
V // CHECK: (cling::Value &) <<<invalid>>> @0x{{.*}}
1717

18+
V.dump(); // CHECK-NEXT: <<<invalid>>>
19+
1820
gCling->evaluate("return 1;", V);
19-
V // CHECK: (cling::Value &) boxes [(int) 1]
21+
V // CHECK-NEXT: (cling::Value &) boxes [(int) 1]
2022

2123
gCling->evaluate("(void)V", V);
2224
V // CHECK-NEXT: (cling::Value &) boxes [(void) ]

test/Prompt/ValuePrinter/Regression.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ auto bla=[](double *x, double *par, int blub){return x[0]*blub;} // CHECK: ((lam
8989

9090
#include <functional>
9191
using namespace std::placeholders;
92-
auto fn_moo = std::bind (bla, _1,_2,10) // CHECK: ERROR in cling's callPrintValue(): missing value string.
92+
auto fn_moo = std::bind (bla, _1,_2,10) // CHECK: <<<undefined>>>
9393
// expected-error {{Could not execute cling::printValue with '{{.*}}'}}
9494
// expected-error {{use of undeclared identifier 'lambda'}}
9595
// expected-error {{expected expression}}

0 commit comments

Comments
 (0)