@@ -37,6 +37,9 @@ static InFlightDiagnostic diagnose(ASTContext &Context, SourceLoc loc,
37
37
void SymbolicValue::print (llvm::raw_ostream &os, unsigned indent) const {
38
38
os.indent (indent);
39
39
switch (representationKind) {
40
+ case RK_UninitMemory:
41
+ os << " uninit\n " ;
42
+ return ;
40
43
case RK_Unknown: {
41
44
os << " unknown(" << (int )getUnknownReason () << " ): " ;
42
45
getUnknownNode ()->dump ();
@@ -76,6 +79,16 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
76
79
return ;
77
80
}
78
81
}
82
+ case RK_DirectAddress:
83
+ case RK_DerivedAddress: {
84
+ SmallVector<unsigned , 4 > accessPath;
85
+ SymbolicValueMemoryObject *memObject = getAddressValue (accessPath);
86
+ os << " Address[" << memObject->getType () << " ] " ;
87
+ interleave (accessPath.begin (), accessPath.end (),
88
+ [&](unsigned idx) { os << idx; }, [&]() { os << " , " ; });
89
+ os << " \n " ;
90
+ break ;
91
+ }
79
92
}
80
93
}
81
94
@@ -85,6 +98,8 @@ void SymbolicValue::dump() const { print(llvm::errs()); }
85
98
// / multiple forms for efficiency, but provide a simpler interface to clients.
86
99
SymbolicValue::Kind SymbolicValue::getKind () const {
87
100
switch (representationKind) {
101
+ case RK_UninitMemory:
102
+ return UninitMemory;
88
103
case RK_Unknown:
89
104
return Unknown;
90
105
case RK_Metatype:
@@ -96,6 +111,9 @@ SymbolicValue::Kind SymbolicValue::getKind() const {
96
111
case RK_Integer:
97
112
case RK_IntegerInline:
98
113
return Integer;
114
+ case RK_DirectAddress:
115
+ case RK_DerivedAddress:
116
+ return Address;
99
117
}
100
118
}
101
119
@@ -105,6 +123,7 @@ SymbolicValue
105
123
SymbolicValue::cloneInto (ASTContext &astContext) const {
106
124
auto thisRK = representationKind;
107
125
switch (thisRK) {
126
+ case RK_UninitMemory:
108
127
case RK_Unknown:
109
128
case RK_Metatype:
110
129
case RK_Function:
@@ -120,9 +139,30 @@ SymbolicValue::cloneInto(ASTContext &astContext) const {
120
139
results.push_back (elt.cloneInto (astContext));
121
140
return getAggregate (results, astContext);
122
141
}
142
+ case RK_DirectAddress:
143
+ case RK_DerivedAddress: {
144
+ SmallVector<unsigned , 4 > accessPath;
145
+ auto *memObject = getAddressValue (accessPath);
146
+ auto *newMemObject = SymbolicValueMemoryObject::create (
147
+ memObject->getType (), memObject->getValue (), astContext);
148
+ return getAddress (newMemObject, accessPath, astContext);
149
+ }
123
150
}
124
151
}
125
152
153
+ // ===----------------------------------------------------------------------===//
154
+ // SymbolicValueMemoryObject implementation
155
+ // ===----------------------------------------------------------------------===//
156
+
157
+ SymbolicValueMemoryObject *
158
+ SymbolicValueMemoryObject::create (Type type, SymbolicValue value,
159
+ ASTContext &astContext) {
160
+ auto *result = astContext.Allocate (sizeof (SymbolicValueMemoryObject),
161
+ alignof (SymbolicValueMemoryObject));
162
+ new (result) SymbolicValueMemoryObject (type, value);
163
+ return (SymbolicValueMemoryObject *)result;
164
+ }
165
+
126
166
// ===----------------------------------------------------------------------===//
127
167
// Integers
128
168
// ===----------------------------------------------------------------------===//
@@ -225,7 +265,7 @@ struct alignas(SourceLoc) UnknownSymbolicValue final
225
265
ASTContext &astContext) {
226
266
auto byteSize =
227
267
UnknownSymbolicValue::totalSizeToAlloc<SourceLoc>(elements.size ());
228
- auto rawMem = astContext.Allocate (byteSize, alignof (UnknownSymbolicValue));
268
+ auto * rawMem = astContext.Allocate (byteSize, alignof (UnknownSymbolicValue));
229
269
230
270
// Placement-new the value inside the memory we just allocated.
231
271
auto value = ::new (rawMem) UnknownSymbolicValue (
@@ -279,6 +319,91 @@ UnknownReason SymbolicValue::getUnknownReason() const {
279
319
return value.unknown ->reason ;
280
320
}
281
321
322
+ // ===----------------------------------------------------------------------===//
323
+ // Addresses
324
+ // ===----------------------------------------------------------------------===//
325
+
326
+ namespace swift {
327
+
328
+ // / This is the representation of a derived address. A derived address refers
329
+ // / to a memory object along with an access path that drills into it.
330
+ struct DerivedAddressValue final
331
+ : private llvm::TrailingObjects<DerivedAddressValue, unsigned > {
332
+ friend class llvm ::TrailingObjects<DerivedAddressValue, unsigned >;
333
+
334
+ SymbolicValueMemoryObject *memoryObject;
335
+
336
+ // / This is the number of indices in the derived address.
337
+ const unsigned numElements;
338
+
339
+ static DerivedAddressValue *create (SymbolicValueMemoryObject *memoryObject,
340
+ ArrayRef<unsigned > elements,
341
+ ASTContext &astContext) {
342
+ auto byteSize =
343
+ DerivedAddressValue::totalSizeToAlloc<unsigned >(elements.size ());
344
+ auto *rawMem = astContext.Allocate (byteSize, alignof (DerivedAddressValue));
345
+
346
+ // Placement initialize the object.
347
+ auto dav =
348
+ ::new (rawMem) DerivedAddressValue (memoryObject, elements.size ());
349
+ std::uninitialized_copy (elements.begin (), elements.end (),
350
+ dav->getTrailingObjects <unsigned >());
351
+ return dav;
352
+ }
353
+
354
+ // / Return the access path for this derived address, which is an array of
355
+ // / indices drilling into the memory object.
356
+ ArrayRef<unsigned > getElements () const {
357
+ return {getTrailingObjects<unsigned >(), numElements};
358
+ }
359
+
360
+ // This is used by the llvm::TrailingObjects base class.
361
+ size_t numTrailingObjects (OverloadToken<unsigned >) const {
362
+ return numElements;
363
+ }
364
+
365
+ private:
366
+ DerivedAddressValue () = delete ;
367
+ DerivedAddressValue (const DerivedAddressValue &) = delete ;
368
+ DerivedAddressValue (SymbolicValueMemoryObject *memoryObject,
369
+ unsigned numElements)
370
+ : memoryObject(memoryObject), numElements(numElements) {}
371
+ };
372
+ } // end namespace swift
373
+
374
+ // / Return a symbolic value that represents the address of a memory object
375
+ // / indexed by a path.
376
+ SymbolicValue SymbolicValue::getAddress (SymbolicValueMemoryObject *memoryObject,
377
+ ArrayRef<unsigned > indices,
378
+ ASTContext &astContext) {
379
+ if (indices.empty ())
380
+ return getAddress (memoryObject);
381
+
382
+ auto dav = DerivedAddressValue::create (memoryObject, indices, astContext);
383
+ SymbolicValue result;
384
+ result.representationKind = RK_DerivedAddress;
385
+ result.value .derivedAddress = dav;
386
+ return result;
387
+ }
388
+
389
+ // / Return the memory object of this reference along with any access path
390
+ // / indices involved.
391
+ SymbolicValueMemoryObject *
392
+ SymbolicValue::getAddressValue (SmallVectorImpl<unsigned > &accessPath) const {
393
+ assert (getKind () == Address);
394
+
395
+ accessPath.clear ();
396
+ if (representationKind == RK_DirectAddress)
397
+ return value.directAddress ;
398
+ assert (representationKind == RK_DerivedAddress);
399
+
400
+ auto *dav = value.derivedAddress ;
401
+
402
+ // The first entry is the object ID, the rest are indices in the accessPath.
403
+ accessPath.assign (dav->getElements ().begin (), dav->getElements ().end ());
404
+ return dav->memoryObject ;
405
+ }
406
+
282
407
// ===----------------------------------------------------------------------===//
283
408
// Higher level code
284
409
// ===----------------------------------------------------------------------===//
0 commit comments