From 12ab4919cc4618fcac4f5d24d45a0e7fdbc4a48c Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Tue, 10 Dec 2024 07:06:23 +0800 Subject: [PATCH] fix[ux]: fix false positive for overflow in type checker (#4385) this commit fixes a false positive for integer overflow in the typechecker involving nested pow operations by filtering `OverflowException` in `_validate_op`. the previous code assumed that `validate_numeric_op` could throw anything besides `InvalidOperation`, but for the `Pow` binop, it can throw `OverflowException`. --------- Co-authored-by: Charles Cooper --- .../codegen/types/numbers/test_exponents.py | 14 ++++++++++++++ vyper/semantics/analysis/utils.py | 2 +- vyper/semantics/types/primitives.py | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/functional/codegen/types/numbers/test_exponents.py b/tests/functional/codegen/types/numbers/test_exponents.py index 702cbcb1dd..28dba59edc 100644 --- a/tests/functional/codegen/types/numbers/test_exponents.py +++ b/tests/functional/codegen/types/numbers/test_exponents.py @@ -173,3 +173,17 @@ def foo(b: int128) -> int128: c.foo(max_power) with tx_failed(): c.foo(max_power + 1) + + +valid_list = [ + """ +@external +def foo() -> uint256: + return (10**18)**2 + """ +] + + +@pytest.mark.parametrize("good_code", valid_list) +def test_exponent_success(good_code): + assert compile_code(good_code) is not None diff --git a/vyper/semantics/analysis/utils.py b/vyper/semantics/analysis/utils.py index a31ce7acc1..8727f3750d 100644 --- a/vyper/semantics/analysis/utils.py +++ b/vyper/semantics/analysis/utils.py @@ -41,7 +41,7 @@ def _validate_op(node, types_list, validation_fn_name): try: _validate_fn(node) ret.append(type_) - except InvalidOperation as e: + except (InvalidOperation, OverflowException) as e: err_list.append(e) if ret: diff --git a/vyper/semantics/types/primitives.py b/vyper/semantics/types/primitives.py index 5c0362e662..dcc4fe8c8e 100644 --- a/vyper/semantics/types/primitives.py +++ b/vyper/semantics/types/primitives.py @@ -173,11 +173,11 @@ def _get_lr(): if isinstance(left, vy_ast.Int): if left.value >= 2**value_bits: raise OverflowException( - "Base is too large, calculation will always overflow", left + f"Base is too large for {self}, calculation will always overflow", left ) elif left.value < -(2**value_bits): raise OverflowException( - "Base is too small, calculation will always underflow", left + f"Base is too small for {self}, calculation will always underflow", left ) elif isinstance(right, vy_ast.Int): if right.value < 0: