@@ -30,6 +30,9 @@ static InFlightDiagnostic diagnose(ASTContext &Context, SourceLoc loc,
30
30
void SymbolicValue::print (llvm::raw_ostream &os, unsigned indent) const {
31
31
os.indent (indent);
32
32
switch (representationKind) {
33
+ case RK_UninitMemory:
34
+ os << " uninit\n " ;
35
+ return ;
33
36
case RK_Unknown: {
34
37
os << " unknown(" << (int )getUnknownReason () << " ): " ;
35
38
getUnknownNode ()->dump ();
@@ -69,6 +72,16 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
69
72
return ;
70
73
}
71
74
}
75
+ case RK_DirectAddress:
76
+ case RK_DerivedAddress: {
77
+ SmallVector<unsigned , 4 > accessPath;
78
+ SymbolicValueMemoryObject *memObject = getAddressValue (accessPath);
79
+ os << " Address[" << memObject->getType () << " ] " ;
80
+ interleave (accessPath.begin (), accessPath.end (),
81
+ [&](unsigned idx) { os << idx; }, [&]() { os << " , " ; });
82
+ os << " \n " ;
83
+ break ;
84
+ }
72
85
}
73
86
}
74
87
@@ -78,6 +91,8 @@ void SymbolicValue::dump() const { print(llvm::errs()); }
78
91
// / multiple forms for efficiency, but provide a simpler interface to clients.
79
92
SymbolicValue::Kind SymbolicValue::getKind () const {
80
93
switch (representationKind) {
94
+ case RK_UninitMemory:
95
+ return UninitMemory;
81
96
case RK_Unknown:
82
97
return Unknown;
83
98
case RK_Metatype:
@@ -89,6 +104,9 @@ SymbolicValue::Kind SymbolicValue::getKind() const {
89
104
case RK_Integer:
90
105
case RK_IntegerInline:
91
106
return Integer;
107
+ case RK_DirectAddress:
108
+ case RK_DerivedAddress:
109
+ return Address;
92
110
}
93
111
}
94
112
@@ -98,6 +116,7 @@ SymbolicValue
98
116
SymbolicValue::cloneInto (llvm::BumpPtrAllocator &allocator) const {
99
117
auto thisRK = representationKind;
100
118
switch (thisRK) {
119
+ case RK_UninitMemory:
101
120
case RK_Unknown:
102
121
case RK_Metatype:
103
122
case RK_Function:
@@ -112,9 +131,29 @@ SymbolicValue::cloneInto(llvm::BumpPtrAllocator &allocator) const {
112
131
results.push_back (elt.cloneInto (allocator));
113
132
return getAggregate (results, allocator);
114
133
}
134
+ case RK_DirectAddress:
135
+ case RK_DerivedAddress: {
136
+ SmallVector<unsigned , 4 > accessPath;
137
+ auto *memObject = getAddressValue (accessPath);
138
+ auto *newMemObject = SymbolicValueMemoryObject::create (
139
+ memObject->getType (), memObject->getValue (), allocator);
140
+ return getAddress (newMemObject, accessPath, allocator);
141
+ }
115
142
}
116
143
}
117
144
145
+ // ===----------------------------------------------------------------------===//
146
+ // SymbolicValueMemoryObject implementation
147
+ // ===----------------------------------------------------------------------===//
148
+
149
+ SymbolicValueMemoryObject *
150
+ SymbolicValueMemoryObject::create (Type type, SymbolicValue value,
151
+ llvm::BumpPtrAllocator &allocator) {
152
+ auto result = allocator.Allocate <SymbolicValueMemoryObject>();
153
+ new (result) SymbolicValueMemoryObject (type, value);
154
+ return result;
155
+ }
156
+
118
157
// ===----------------------------------------------------------------------===//
119
158
// Integers
120
159
// ===----------------------------------------------------------------------===//
@@ -269,6 +308,91 @@ UnknownReason SymbolicValue::getUnknownReason() const {
269
308
return value.unknown ->reason ;
270
309
}
271
310
311
+ // ===----------------------------------------------------------------------===//
312
+ // Addresses
313
+ // ===----------------------------------------------------------------------===//
314
+
315
+ namespace swift {
316
+
317
+ // / This is the representation of a derived address. A derived address refers
318
+ // / to a memory object along with an access path that drills into it.
319
+ struct DerivedAddressValue final
320
+ : private llvm::TrailingObjects<DerivedAddressValue, unsigned > {
321
+ friend class llvm ::TrailingObjects<DerivedAddressValue, unsigned >;
322
+
323
+ SymbolicValueMemoryObject *memoryObject;
324
+
325
+ // / This is the number of indices in the derived address.
326
+ const unsigned numElements;
327
+
328
+ static DerivedAddressValue *create (SymbolicValueMemoryObject *memoryObject,
329
+ ArrayRef<unsigned > elements,
330
+ llvm::BumpPtrAllocator &allocator) {
331
+ auto byteSize =
332
+ DerivedAddressValue::totalSizeToAlloc<unsigned >(elements.size ());
333
+ auto rawMem = allocator.Allocate (byteSize, alignof (DerivedAddressValue));
334
+
335
+ // Placement initialize the object.
336
+ auto dav =
337
+ ::new (rawMem) DerivedAddressValue (memoryObject, elements.size ());
338
+ std::uninitialized_copy (elements.begin (), elements.end (),
339
+ dav->getTrailingObjects <unsigned >());
340
+ return dav;
341
+ }
342
+
343
+ // / Return the element constants for this aggregate constant. These are
344
+ // / known to all be constants.
345
+ ArrayRef<unsigned > getElements () const {
346
+ return {getTrailingObjects<unsigned >(), numElements};
347
+ }
348
+
349
+ // This is used by the llvm::TrailingObjects base class.
350
+ size_t numTrailingObjects (OverloadToken<unsigned >) const {
351
+ return numElements;
352
+ }
353
+
354
+ private:
355
+ DerivedAddressValue () = delete ;
356
+ DerivedAddressValue (const DerivedAddressValue &) = delete ;
357
+ DerivedAddressValue (SymbolicValueMemoryObject *memoryObject,
358
+ unsigned numElements)
359
+ : memoryObject(memoryObject), numElements(numElements) {}
360
+ };
361
+ } // end namespace swift
362
+
363
+ // / Return a symbolic value that represents the address of a memory object
364
+ // / indexed by a path.
365
+ SymbolicValue SymbolicValue::getAddress (SymbolicValueMemoryObject *memoryObject,
366
+ ArrayRef<unsigned > indices,
367
+ llvm::BumpPtrAllocator &allocator) {
368
+ if (indices.empty ())
369
+ return getAddress (memoryObject);
370
+
371
+ auto dav = DerivedAddressValue::create (memoryObject, indices, allocator);
372
+ SymbolicValue result;
373
+ result.representationKind = RK_DerivedAddress;
374
+ result.value .derivedAddress = dav;
375
+ return result;
376
+ }
377
+
378
+ // / Return the memory object of this reference along with any access path
379
+ // / indices involved.
380
+ SymbolicValueMemoryObject *
381
+ SymbolicValue::getAddressValue (SmallVectorImpl<unsigned > &accessPath) const {
382
+ assert (getKind () == Address);
383
+
384
+ accessPath.clear ();
385
+ if (representationKind == RK_DirectAddress)
386
+ return value.directAddress ;
387
+ assert (representationKind == RK_DerivedAddress);
388
+
389
+ auto *dav = value.derivedAddress ;
390
+
391
+ // The first entry is the object ID, the rest are indices in the accessPath.
392
+ accessPath.assign (dav->getElements ().begin (), dav->getElements ().end ());
393
+ return dav->memoryObject ;
394
+ }
395
+
272
396
// ===----------------------------------------------------------------------===//
273
397
// Higher level code
274
398
// ===----------------------------------------------------------------------===//
0 commit comments