Skip to content

Commit

Permalink
chore: set raw_revert as terminus node (#3342)
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
tserg authored Apr 7, 2023
1 parent 026f85f commit 62d2cfa
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
38 changes: 38 additions & 0 deletions tests/parser/syntax/test_unbalanced_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
]


Expand Down Expand Up @@ -126,6 +156,14 @@ def test() -> int128:
return 1
return 1
""",
"""
@external
def foo() -> int128:
if True:
return 123
else:
raw_revert(b"vyper")
""",
]


Expand Down
2 changes: 2 additions & 0 deletions vyper/builtins/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion vyper/codegen/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 62d2cfa

Please sign in to comment.