17
17
#include " llvm/Support/TrailingObjects.h"
18
18
using namespace swift ;
19
19
20
+ namespace swift {
21
+ llvm::cl::opt<unsigned >
22
+ ConstExprLimit (" constexpr-limit" , llvm::cl::init(512 ),
23
+ llvm::cl::desc (" Number of instructions interpreted in a"
24
+ " constexpr function" ));
25
+ }
26
+
20
27
template <typename ... T, typename ... U>
21
28
static InFlightDiagnostic diagnose (ASTContext &Context, SourceLoc loc,
22
29
Diag<T...> diag, U &&... args) {
@@ -92,25 +99,26 @@ SymbolicValue::Kind SymbolicValue::getKind() const {
92
99
}
93
100
}
94
101
95
- // / Clone this SymbolicValue into the specified allocator and return the new
102
+ // / Clone this SymbolicValue into the specified ASTContext and return the new
96
103
// / version. This only works for valid constants.
97
104
SymbolicValue
98
- SymbolicValue::cloneInto (llvm::BumpPtrAllocator &allocator ) const {
105
+ SymbolicValue::cloneInto (ASTContext &astContext ) const {
99
106
auto thisRK = representationKind;
100
107
switch (thisRK) {
101
108
case RK_Unknown:
102
109
case RK_Metatype:
103
110
case RK_Function:
111
+ assert (0 && " cloning this representation kind is not supported" );
104
112
case RK_IntegerInline:
105
113
case RK_Integer:
106
- return SymbolicValue::getInteger (getIntegerValue (), allocator );
114
+ return SymbolicValue::getInteger (getIntegerValue (), astContext );
107
115
case RK_Aggregate: {
108
116
auto elts = getAggregateValue ();
109
117
SmallVector<SymbolicValue, 4 > results;
110
118
results.reserve (elts.size ());
111
119
for (auto elt : elts)
112
- results.push_back (elt.cloneInto (allocator ));
113
- return getAggregate (results, allocator );
120
+ results.push_back (elt.cloneInto (astContext ));
121
+ return getAggregate (results, astContext );
114
122
}
115
123
}
116
124
}
@@ -128,14 +136,14 @@ SymbolicValue SymbolicValue::getInteger(int64_t value, unsigned bitWidth) {
128
136
}
129
137
130
138
SymbolicValue SymbolicValue::getInteger (const APInt &value,
131
- llvm::BumpPtrAllocator &allocator ) {
139
+ ASTContext &astContext ) {
132
140
// In the common case, we can form an inline representation.
133
141
unsigned numWords = value.getNumWords ();
134
142
if (numWords == 1 )
135
143
return getInteger (value.getRawData ()[0 ], value.getBitWidth ());
136
144
137
145
// Copy the integers from the APInt into the bump pointer.
138
- auto *words = allocator .Allocate <uint64_t >(numWords);
146
+ auto *words = astContext .Allocate <uint64_t >(numWords). data ( );
139
147
std::uninitialized_copy (value.getRawData (), value.getRawData () + numWords,
140
148
words);
141
149
@@ -173,9 +181,10 @@ unsigned SymbolicValue::getIntegerValueBitWidth() const {
173
181
// / This returns a constant Symbolic value with the specified elements in it.
174
182
// / This assumes that the elements lifetime has been managed for this.
175
183
SymbolicValue SymbolicValue::getAggregate (ArrayRef<SymbolicValue> elements,
176
- llvm::BumpPtrAllocator &allocator) {
177
- // Copy the integers from the APInt into the bump pointer.
178
- auto *resultElts = allocator.Allocate <SymbolicValue>(elements.size ());
184
+ ASTContext &astContext) {
185
+ // Copy the elements into the bump pointer.
186
+ auto *resultElts =
187
+ astContext.Allocate <SymbolicValue>(elements.size ()).data ();
179
188
std::uninitialized_copy (elements.begin (), elements.end (), resultElts);
180
189
181
190
SymbolicValue result;
@@ -212,10 +221,10 @@ struct alignas(SourceLoc) UnknownSymbolicValue final
212
221
213
222
static UnknownSymbolicValue *create (SILNode *node, UnknownReason reason,
214
223
ArrayRef<SourceLoc> elements,
215
- llvm::BumpPtrAllocator &allocator ) {
224
+ ASTContext &astContext ) {
216
225
auto byteSize =
217
226
UnknownSymbolicValue::totalSizeToAlloc<SourceLoc>(elements.size ());
218
- auto rawMem = allocator .Allocate (byteSize, alignof (UnknownSymbolicValue));
227
+ auto rawMem = astContext .Allocate (byteSize, alignof (UnknownSymbolicValue));
219
228
220
229
// Placement-new the value inside the memory we just allocated.
221
230
auto value = ::new (rawMem) UnknownSymbolicValue (
@@ -245,12 +254,12 @@ struct alignas(SourceLoc) UnknownSymbolicValue final
245
254
246
255
SymbolicValue SymbolicValue::getUnknown (SILNode *node, UnknownReason reason,
247
256
llvm::ArrayRef<SourceLoc> callStack,
248
- llvm::BumpPtrAllocator &allocator ) {
257
+ ASTContext &astContext ) {
249
258
assert (node && " node must be present" );
250
259
SymbolicValue result;
251
260
result.representationKind = RK_Unknown;
252
261
result.value .unknown =
253
- UnknownSymbolicValue::create (node, reason, callStack, allocator );
262
+ UnknownSymbolicValue::create (node, reason, callStack, astContext );
254
263
return result;
255
264
}
256
265
@@ -284,8 +293,8 @@ static SILDebugLocation skipInternalLocations(SILDebugLocation loc) {
284
293
return loc;
285
294
286
295
// Zip through inlined call site information that came from the
287
- // implementation guts of the tensor library. We want to report the
288
- // message inside the user's code, not in the guts we inlined through.
296
+ // implementation guts of the library. We want to report the message inside
297
+ // the user's code, not in the guts we inlined through.
289
298
for (; auto ics = ds->InlinedCallSite ; ds = ics) {
290
299
// If we found a valid inlined-into location, then we are good.
291
300
if (ds->Loc .getSourceLoc ().isValid ())
@@ -351,7 +360,8 @@ void SymbolicValue::emitUnknownDiagnosticNotes(SILLocation fallbackLoc) {
351
360
break ;
352
361
case UnknownReason::TooManyInstructions:
353
362
// TODO: Should pop up a level of the stack trace.
354
- error = " expression is too large to evaluate at compile-time" ;
363
+ error = " exceeded instruction limit: " + std::to_string (ConstExprLimit) +
364
+ " when evaluating the expression at compile time" ;
355
365
break ;
356
366
case UnknownReason::Loop:
357
367
error = " control flow loop found" ;
@@ -377,7 +387,7 @@ void SymbolicValue::emitUnknownDiagnosticNotes(SILLocation fallbackLoc) {
377
387
unsigned originalDiagnosticLineNumber =
378
388
SM.getLineNumber (fallbackLoc.getSourceLoc ());
379
389
for (auto &sourceLoc : llvm::reverse (getUnknownCallStack ())) {
380
- // Skip known sources.
390
+ // Skip unknown sources.
381
391
if (!sourceLoc.isValid ())
382
392
continue ;
383
393
// Also skip notes that point to the same line as the original error, for
0 commit comments