hyperledger / solang

Solidity Compiler for Solana and Polkadot
https://solang.readthedocs.io/
Apache License 2.0
1.25k stars 208 forks source link

Type inference bug for literals in arithmetic expressions that are implicitly cast #1535

Open bkushigian opened 11 months ago

bkushigian commented 11 months ago

I'm assuming this is a bug in solang and not solc, but I haven't dug into the specs on how type promotions work for shifts. The following code compiles with solc but not solang:

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

contract MultiRolesAuthority {
    function shiftTypeInference(uint8 role) public virtual returns (bytes32) {
        bytes32 x = bytes32(1 << role);
        return x;
    }
}

solang is typing 1 << role as a u8, because that is what role is.

$ solang 
=====  Error: src/auth/authorities/MultiRolesAuthority.sol  =====
error: conversion to bytes32 from uint8 not allowed
  ┌─ /Users/benku/Certora/tests/solmate/src/auth/authorities/MultiRolesAuthority.sol:8:25
  │
8 │             bytes32 x = bytes32(1 << role);
  │                         ^^^^^^^^^^^^^^^^^^

Similarly, in the following code, we have int256 x receiving 5 ** 10. I think solidity is emitting a cast on the result of 5 ** 10 (or something, I don't know EVM bytecode), while solang is inferring that 5 ** 10 is a int256 and therefore its arguments must be signed.

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

contract LiteralTypeInfer {
    function typeInfer() public pure returns (int256 x) {
        x = 5 ** 10;
    }
}