Skip to content

Constant initializer modifiability check ignores subscript index #5275

Description

@xrchz

Version

v0.4.4+commit.cd74ce4f5 (cd74ce4f57e3771aeeab8f061fa3be45bfe8a29c)

Description

A runtime-dependent expression is correctly rejected when used directly in a constant initializer, but is accepted when used as the index of a constant composite.

For example, this is rejected as expected:

B: constant(uint256) = block.number

However, this compiles successfully:

A: constant(uint256[2]) = [1, 2]
B: constant(uint256) = A[block.number]

The same occurs through a constant struct:

struct S:
    xs: uint256[2]

A: constant(S) = S(xs=[1, 2])
B: constant(uint256) = A.xs[block.number]

Expected behavior

Both examples using block.number as an index should be rejected with StateAccessViolation, consistently with other runtime-dependent constant initializers.

Likely cause

check_modifiability does not have a recursive Subscript case. It falls through to get_expr_info(node). _ExprAnalyser.get_expr_info handles Subscript by copying the base expression's ExprInfo, including its modifiability:

if isinstance(node, vy_ast.Subscript):
    info = self.get_expr_info(node.value)
    return info.copy_with_type(t)

Consequently, a subscript whose base is constant is classified as constant without checking the index expression.

A possible fix is to make check_modifiability check both node.value and node.slice for Subscript, with regression tests covering direct constant arrays and fields of constant structs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions