Solidity: ICE in convertType() when calling functions bound to structs and arrays with calldata parameters

Created on 3 Nov 2020  路  3Comments  路  Source: ethereum/solidity

Env: hardhat
Compiler: 0.7.4

Try to compile this code with 0.7.4 .

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

struct Task {
    address[] actions;
}

struct TaskReceipt {
    uint256 index;
    Task[] tasks;
}

library GelatoTaskReceipt {
    function task(TaskReceipt calldata _taskReceipt)
        internal
        pure
        returns (Task memory)
    {
        return _taskReceipt.tasks[_taskReceipt.index];
    }
}

contract Example {
    using GelatoTaskReceipt for TaskReceipt;

    function exec(TaskReceipt calldata _taskReceipt) external pure {
        for (uint256 i = 0; i < _taskReceipt.task().actions.length; i++) {}
    }
}

Accessing fields on the Task memory returned from GelatoTaskReceipt.task seems to be the issue.

for (uint256 i = 0; i < _taskReceipt.task().actions.length; i++) {}

InternalCompilerError: Internal compiler error (/Users/distiller/project/libsolidity/codegen/CompilerUtils.cpp:1057)

The problem seems to go away if you use memory data location instead.

In a previous compiler version (e.g. 0.6.12) using calldata for the same code did compile without error by the way.

bug should compile without error

All 3 comments

The bound function seems to be the issue.

The bound function seems to be the issue.

bound function and calldata. This might be unrelated but I reported a different bug for solc 0.6.9 that also had to do with bound function and calldata before: https://github.com/ethereum/solidity/issues/9172

Yeah, looks like it's both. Below is the smallest repro I could find. It stops happening if I change the location to memory, remove using or use a type different than a struct.

It works in 0.6.9. In all the later versions it triggers an ICE.

pragma experimental ABIEncoderV2;

struct S {
    uint x;
}

library L {
    function f(S calldata) internal pure {}
}

contract C {
    using L for S;

    function run(S calldata _s) external pure {
        _s.f();
    }
}
Internal compiler error during compilation:
/solidity/libsolidity/codegen/CompilerUtils.cpp(1055): Throw in function void solidity::frontend::CompilerUtils::convertType(const solidity::frontend::Type&, const solidity::frontend::Type&, bool, bool, bool)
Dynamic exception type: boost::wrapexcept<solidity::langutil::InternalCompilerError>
std::exception::what:
[solidity::util::tag_comment*] =



md5-1e41b74203d5a26f66b36e02a9a59e77



Internal compiler error during compilation:
/solidity/libsolidity/codegen/CompilerUtils.cpp(1024): Throw in function void solidity::frontend::CompilerUtils::convertType(const solidity::frontend::Type&, const solidity::frontend::Type&, bool, bool, bool)
Dynamic exception type: boost::wrapexcept
std::exception::what: Invalid conversion to calldata type.
[solidity::util::tag_comment*] = Invalid conversion to calldata type.
```

The example from the issue description works on 0.6.8 and fails in the same way since 0.6.10. On 0.6.9 it triggers UnimplementedFeatureError because the struct contains a dynamic array.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

axic picture axic  路  3Comments

ddeclerck picture ddeclerck  路  3Comments

Dohtar1337 picture Dohtar1337  路  4Comments

kkagill picture kkagill  路  4Comments

chriseth picture chriseth  路  3Comments