Skip to content

Commit 459271d

Browse files
committed
Fix ArrayElementPropagation handling of negative index
Convert an incorrect assert into correct code. Fixes rdar://80444607 (Swift compiler segfault on “[1][-1]”)
1 parent a34d757 commit 459271d

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,10 @@ bool ArrayAllocation::replaceGetElements() {
214214
if (ConstantIndex == None)
215215
continue;
216216

217-
assert(*ConstantIndex >= 0 && "Must have a positive index");
217+
// ElementValueMap keys are unsigned. Avoid implicit signed-unsigned
218+
// conversion from an invalid index to a valid index.
219+
if (*ConstantIndex < 0)
220+
continue;
218221

219222
auto EltValueIt = ElementValueMap.find(*ConstantIndex);
220223
if (EltValueIt == ElementValueMap.end())

test/SILOptimizer/array_element_propagation_ossa.sil

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,37 @@ sil [ossa] @append_contentsOf_int : $@convention(thin) () -> () {
251251
return %19 : $()
252252
}
253253

254+
// Ignore an invalid negative index without crashing.
255+
//
256+
// CHECK-LABEL: sil [ossa] @negative_index
257+
// CHECK: store %{{[0-9]+}} to [trivial]
258+
// CHECK: [[GETF:%.*]] = function_ref @getElement : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
259+
// CHECK: apply [[GETF]](%15, %17, %19, %7) : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
260+
// CHECK-LABEL: // end sil function 'negative_index'
261+
sil [ossa] @negative_index : $@convention(thin) () -> () {
262+
bb0:
263+
%0 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject // user: %3
264+
%1 = integer_literal $Builtin.Int64, 1
265+
%2 = struct $MyInt (%1 : $Builtin.Int64)
266+
%3 = apply %0() : $@convention(thin) () -> @owned AnyObject
267+
%4 = metatype $@thin MyArray<MyInt>.Type
268+
%5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
269+
%6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray<MyInt>.Type) -> @owned (MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
270+
(%7, %8) = destructure_tuple %6 : $(MyArray<MyInt>, UnsafeMutablePointer<MyInt>)
271+
%9 = struct_extract %8 : $UnsafeMutablePointer<MyInt>, #UnsafeMutablePointer._rawValue
272+
%10 = pointer_to_address %9 : $Builtin.RawPointer to [strict] $*MyInt
273+
%11 = integer_literal $Builtin.Int64, 0
274+
%12 = struct $MyInt (%11 : $Builtin.Int64)
275+
store %12 to [trivial] %10 : $*MyInt
276+
%14 = integer_literal $Builtin.Int64, -1
277+
%15 = struct $MyInt (%14 : $Builtin.Int64)
278+
%16 = function_ref @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyBool
279+
%17 = apply %16(%7) : $@convention(method) (@guaranteed MyArray<MyInt>) -> MyBool
280+
%18 = function_ref @checkSubscript : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> _MyDependenceToken
281+
%19 = apply %18(%12, %17, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray<MyInt>) -> _MyDependenceToken
282+
%20 = function_ref @getElement : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
283+
%21 = apply %20(%15, %17, %19, %7) : $@convention(method) (MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray<MyInt>) -> MyInt
284+
destroy_value %7 : $MyArray<MyInt>
285+
%23 = tuple ()
286+
return %23 : $()
287+
}

0 commit comments

Comments
 (0)