Skip to content

missing execution paths for HexBytes #4608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
cyberthirst opened this issue Apr 25, 2025 · 0 comments · May be fixed by #4630
Open

missing execution paths for HexBytes #4608

cyberthirst opened this issue Apr 25, 2025 · 0 comments · May be fixed by #4630
Labels
needs triage needs triage

Comments

@cyberthirst
Copy link
Collaborator

Version Information

  • vyper Version (output of vyper --version): b635696

What's your issue about?

Per @trocher

The AST node HexBytes is used to represent byte arrays in the Vyper AST, similar to the Bytes node, but with a hexadecimal representation. There should be no reason to have different behavior for these two nodes, but the HexBytes node is not always handled in the same way as the Bytes node.

  1. In convert.py::_literal_int(), there are no paths to handle the HexBytes node, which means that upon converting a HexBytes node to an integer (convert(x'0102', uint256)), the compiler will fail with CompilerPanic: unreachable. Furthermore, in case the out type is signed, the HexBytes value would not sign-extend if the first issue was fixed.
def _literal_int(expr, arg_typ, out_typ):
    # TODO: possible to reuse machinery from expr.py?
    if isinstance(expr, vy_ast.Hex):
        val = int(expr.value, 16)
    elif isinstance(expr, vy_ast.Bytes):  # Missing HexBytes
        val = int.from_bytes(expr.value, "big")
    elif isinstance(expr, (vy_ast.Int, vy_ast.Decimal, vy_ast.NameConstant)):
        val = expr.value
    else:  # pragma: no cover
        raise CompilerPanic("unreachable")

    # Missing HexBytes
    if isinstance(expr, (vy_ast.Hex, vy_ast.Bytes)) and out_typ.is_signed:
        val = _signextend(expr, val, arg_typ)
  1. Similarly, in convert.py::_literal_decimal(), in case the out type is signed, the HexBytes value is not sign-extended, note that in the current state of the codebase, this is not reachable because of Codegen panic when Converting literal bytes to decimal:
if isinstance(expr, (vy_ast.Hex, vy_ast.Bytes)) and out_typ.is_signed:
    val = _signextend(expr, val, arg_typ)
  1. In the len builtin defined in functions.py, a special path to constant fold Bytes nodes is defined, but not for HexBytes nodes. This means that the following code will not be folded:
@external
def foo():
    a: uint256 = len(x'0102')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage needs triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant