Skip to content

fix(sema): reject rational expressions in abi.encode* arguments#1892

Open
aryanbaranwal001 wants to merge 1 commit intohyperledger-solang:mainfrom
aryanbaranwal001:fix/abi-encode-rational-guard
Open

fix(sema): reject rational expressions in abi.encode* arguments#1892
aryanbaranwal001 wants to merge 1 commit intohyperledger-solang:mainfrom
aryanbaranwal001:fix/abi-encode-rational-guard

Conversation

@aryanbaranwal001
Copy link
Copy Markdown

This PR fixes a compiler panic when a rational (fractional/decimal) expression is passed as an argument to abi.encode*.

The root cause is that sema's abi.encode* argument resolution loop at sema/builtin.rs:1403 only guards against mapping and recursive types. It has no guard for Type::Rational, which is a sema level placeholder for expressions involving decimal literals, 24.24, 1 - 24.24, 1.5 * 2 that haven't been coerced to a concrete integer type, which only happens when a target type is available (e.g. uint256 x = 32). The rational expression is stored in AST as Type::Rational without any error which then passes into codegen.

codegen/expression.rs:1048 matches ast::Builtin::AbiEncodePacked and calls abi_encode_packed() at codegen/expression.rs:1853.

abi_encode_packed maps expression() over each arg and passes the result to abi_encode() at codegen/expression.rs:1858.

abi_encode calls calculate_size_args() at codegen/encoding/mod.rs:48, which calls get_expr_size() at codegen/encoding/mod.rs:176.

get_expr_size matches on the expression's type. Type::Rational hits the unreachable arm at codegen/encoding/mod.rs:1454–1456:

Type::UserType(_) | Type::Unresolved | Type::Rational => unreachable!("Type should not exist in codegen")

Fix

Add a Type::Rational guard in the arg resolution loop at sema/builtin.rs:1407, immediately after the existing mapping/recursive check:

if matches!(ty, Type::Rational) {
    diagnostics.push(Diagnostic::error(
        arg.loc(),
        "rational expression has no concrete type; cast to an integer type before encoding".to_string(),
    ));
    return Err(());
}

This makes sema reject unresolved rational expressions before they reach codegen. The fix covers all abi.encode* variants of abi.encode, abi.encodePacked, abi.encodeWithSelector, and abi.encodeWithSignature, since they all share the same loop at sema/builtin.rs:1403.

Previously panicking inputs:

  • abi.encodePacked(1 - 24.24);
  • abi.encode(1.7);

Reproduces on polkadot, solana, and evm targets.

Signed-off-by: Aryan Baranwal <aryanbaranwal131214@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiler panic in codegen: unreachable!("Type should not exist in codegen") when abi-encoding a rational expression

1 participant