From 62d2cfaaf8372ec5f2e8ce14ead4c24a05cccb09 Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Sat, 8 Apr 2023 00:01:59 +0800 Subject: [PATCH] chore: set `raw_revert` as terminus node (#3342) Set `raw_revert` as a terminal statement, similar to `selfdestruct`. For example, this contract should not compile because the last statement can never be reached. ``` @external def foo(a: Bytes[100]) -> uint256: raw_revert(a) b: uint256 = 76 ``` --- tests/parser/syntax/test_unbalanced_return.py | 38 +++++++++++++++++++ vyper/builtins/functions.py | 2 + vyper/codegen/core.py | 5 ++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tests/parser/syntax/test_unbalanced_return.py b/tests/parser/syntax/test_unbalanced_return.py index 653c2a63ef..5337b4b677 100644 --- a/tests/parser/syntax/test_unbalanced_return.py +++ b/tests/parser/syntax/test_unbalanced_return.py @@ -64,6 +64,36 @@ def valid_address(sender: address) -> bool: """, StructureException, ), + ( + """ +@internal +def foo() -> bool: + raw_revert(b"vyper") + return True + """, + StructureException, + ), + ( + """ +@internal +def foo() -> bool: + raw_revert(b"vyper") + x: uint256 = 3 + """, + StructureException, + ), + ( + """ +@internal +def foo(x: uint256) -> bool: + if x == 2: + raw_revert(b"vyper") + a: uint256 = 3 + else: + return False + """, + StructureException, + ), ] @@ -126,6 +156,14 @@ def test() -> int128: return 1 return 1 """, + """ +@external +def foo() -> int128: + if True: + return 123 + else: + raw_revert(b"vyper") + """, ] diff --git a/vyper/builtins/functions.py b/vyper/builtins/functions.py index 6c00678d5c..f81fb20a64 100644 --- a/vyper/builtins/functions.py +++ b/vyper/builtins/functions.py @@ -1255,6 +1255,8 @@ def build_IR(self, expr, args, kwargs, contact): class RawRevert(BuiltinFunction): _id = "raw_revert" _inputs = [("data", BytesT.any())] + _return_type = None + _is_terminus = True def fetch_call_return(self, node): return None diff --git a/vyper/codegen/core.py b/vyper/codegen/core.py index 439478a4c4..1cc601413c 100644 --- a/vyper/codegen/core.py +++ b/vyper/codegen/core.py @@ -917,7 +917,10 @@ def eval_seq(ir_node): # TODO move return checks to vyper/semantics/validation def is_return_from_function(node): - if isinstance(node, vy_ast.Expr) and node.get("value.func.id") == "selfdestruct": + if isinstance(node, vy_ast.Expr) and node.get("value.func.id") in ( + "raw_revert", + "selfdestruct", + ): return True if isinstance(node, (vy_ast.Return, vy_ast.Raise)): return True