Skip to content

Commit 6d7082e

Browse files
committed
Make Value's destructor safe by updating ArrValue and StrValue
1 parent e56b4f3 commit 6d7082e

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed

clang/include/clang/Interpreter/Value.h

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,19 @@ class REPL_EXTERNAL_VISIBILITY Value final {
185185
}
186186
REPL_BUILTIN_TYPES
187187
#undef X
188+
189+
Builtins(const Builtins &) = delete;
190+
Builtins &operator=(const Builtins &) = delete;
188191
};
189192

190193
/// Represents an array of `Value` elements.
191194
struct ArrValue {
192-
std::vector<Value> Elements;
195+
Value *Elements;
193196
uint64_t ArrSize;
194-
ArrValue(uint64_t Size) : ArrSize(Size) {
195-
Elements.reserve(ArrSize);
196-
for (uint64_t I = 0; I < ArrSize; ++I)
197-
Elements.emplace_back();
198-
}
197+
ArrValue(uint64_t Size) : Elements(new Value[Size]), ArrSize(Size) {}
198+
~ArrValue() { delete[] Elements; }
199+
ArrValue(const ArrValue &) = delete;
200+
ArrValue &operator=(const ArrValue &) = delete;
199201
};
200202

201203
/// Represents a pointer. Holds the address and optionally a pointee `Value`.
@@ -207,13 +209,37 @@ class REPL_EXTERNAL_VISIBILITY Value final {
207209
if (Pointee != nullptr)
208210
delete Pointee;
209211
}
212+
213+
PtrValue(const PtrValue &) = delete;
214+
PtrValue &operator=(const PtrValue &) = delete;
210215
};
211216

212217
/// Represents a string value (wrapper over std::string).
213218
struct StrValue {
214-
std::string StringBuf;
215-
StrValue(std::string str) : StringBuf(std::move(str)) {}
216-
~StrValue() = default;
219+
char *Buf;
220+
size_t Length;
221+
222+
StrValue(const char *Str) {
223+
Length = strlen(Str);
224+
Buf = new char[Length + 1];
225+
memcpy(Buf, Str, Length);
226+
Buf[Length] = '\0';
227+
}
228+
229+
~StrValue() { delete[] Buf; }
230+
231+
StrValue(const StrValue &) = delete;
232+
StrValue &operator=(const StrValue &) = delete;
233+
234+
void set(const char *Str) {
235+
delete[] Buf;
236+
Length = strlen(Str);
237+
Buf = new char[Length + 1];
238+
memcpy(Buf, Str, Length);
239+
Buf[Length] = '\0';
240+
}
241+
242+
const char *get() const { return Buf; }
217243
};
218244

219245
public:
@@ -230,7 +256,7 @@ class REPL_EXTERNAL_VISIBILITY Value final {
230256
std::optional<ValueCleanup> Cleanup = std::nullopt;
231257

232258
public:
233-
Value() = default;
259+
Value() : VKind(K_None) {}
234260
explicit Value(QualType Ty) : Ty(Ty), VKind(K_None) {}
235261
Value(const Value &RHS);
236262
Value(Value &&RHS)
@@ -335,23 +361,18 @@ class REPL_EXTERNAL_VISIBILITY Value final {
335361
// ---- String accessors ----
336362
void setStrVal(const char *buf) {
337363
assert(isStr() && "Not a Str");
338-
asStr().StringBuf = buf;
339-
}
340-
341-
StringRef getStrVal() {
342-
assert(isStr() && "Not a Str");
343-
return StringRef(asStr().StringBuf);
364+
asStr().set(buf);
344365
}
345366

346-
const StringRef getStrVal() const {
367+
const char *getStrVal() const {
347368
assert(isStr() && "Not a Str");
348-
return StringRef(asStr().StringBuf);
369+
return asStr().get();
349370
}
350371

351372
// ---- Array accessors ----
352373
uint64_t getArraySize() const { return asArray().ArrSize; }
353374

354-
uint64_t getArrayInitializedElts() const { return asArray().Elements.size(); }
375+
uint64_t getArrayInitializedElts() const { return asArray().ArrSize; }
355376

356377
Value &getArrayInitializedElt(unsigned I) {
357378
assert(isArray() && "Invalid accessor");
@@ -427,7 +448,7 @@ class REPL_EXTERNAL_VISIBILITY Value final {
427448
VKind = K_Pointer;
428449
}
429450

430-
void MakeStr(std::string Str = "") {
451+
void MakeStr(const char *Str) {
431452
assert(isAbsent() && "Bad state change");
432453
new ((void *)(char *)&Data) StrValue(Str);
433454
VKind = K_Str;

clang/lib/Interpreter/InterpreterValuePrinter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,16 @@ static std::string FunctionToString(ASTContext &Ctx, QualType QT,
155155
return Str;
156156
}
157157

158+
static std::string CharPtrToString(const char *Ptr) {
159+
if (!Ptr)
160+
return "0";
161+
162+
std::string Result = "\"";
163+
Result += Ptr;
164+
Result += '"';
165+
return Result;
166+
}
167+
158168
namespace clang {
159169

160170
std::string ValueToString::toString(const Value *Buf) {
@@ -291,7 +301,7 @@ std::string ValueToString::PointerToString(const Value &P) {
291301
// char* -> print string literal
292302
if (PointeeTy->isCharType()) {
293303
if (P.HasPointee() && P.getPointerPointee().isStr())
294-
return "\"" + P.getPointerPointee().getStrVal().str() + "\"";
304+
return CharPtrToString(P.getPointerPointee().getStrVal());
295305
return std::to_string(P.getAddr());
296306
}
297307

clang/lib/Interpreter/Value.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Value::Value(const Value &RHS)
162162
break;
163163
}
164164
case K_Str:
165-
MakeStr(RHS.getStrVal().str());
165+
MakeStr(RHS.getStrVal());
166166
break;
167167
}
168168
}

0 commit comments

Comments
 (0)