diff --git a/tests/functional/codegen/features/iteration/test_for_range.py b/tests/functional/codegen/features/iteration/test_for_range.py index eedce46829..e64a35811d 100644 --- a/tests/functional/codegen/features/iteration/test_for_range.py +++ b/tests/functional/codegen/features/iteration/test_for_range.py @@ -414,3 +414,19 @@ def foo(a: {typ}) -> {typ}: assert c.foo(100) == 6 assert c.foo(1) == 666 assert c.foo(0) == 31337 + + +def test_for_range_signed_int_overflow(get_contract, tx_failed): + code = """ +@external +def foo() -> DynArray[int256, 10]: + res: DynArray[int256, 10] = empty(DynArray[int256, 10]) + x:int256 = max_value(int256) + y:int256 = min_value(int256)+2 + for i:int256 in range(x,y , bound=10): + res.append(i) + return res + """ + c = get_contract(code) + with tx_failed(): + c.foo() diff --git a/vyper/codegen/stmt.py b/vyper/codegen/stmt.py index e6baea75f7..084b4a1a49 100644 --- a/vyper/codegen/stmt.py +++ b/vyper/codegen/stmt.py @@ -255,7 +255,7 @@ def _parse_For_range(self): with end.cache_when_complex("end") as (b1, end): # note: the check for rounds<=rounds_bound happens in asm # generation for `repeat`. - clamped_start = clamp("le", start, end) + clamped_start = clamp("sle" if target_type.is_signed else "le", start, end) rounds = b1.resolve(IRnode.from_list(["sub", end, clamped_start])) rounds_bound = kwargs.pop("bound").int_value() else: