argotorg / argotorg/solidity

Copying `calldata` and `memory` arrays to storage reports ICE

Open
#14,837 2 comments 3 reactions 0 assignees View on GitHub
bug :bug:
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
21

Description

## Description

When copying a `memory` or `calldata` array to storage, solc will report the compile-time error: `Error: Unimplemented feature (/solidity/libsolidity/codegen/ArrayUtils.cpp:227):Copying of type struct Counter.Discount calldata[] calldata to storage not yet supported.`
However, this works if said array is a member of a struct and has a data location of `calldata`.

## Environment

- Compiler version: v0.8.24
- Target EVM version (as per compiler settings): paris
- Framework/IDE (e.g. Truffle or Remix): Foundry
- EVM execution environment / backend / blockchain client:
- Operating system: Ubuntu 20.04

## Steps to Reproduce

For the following PoC, `setTiers` will work correctly and copy the contents of `_tiers` to `tiers`. Yet `setDiscounts` will produce the ICE provided above with `forge build`. `setTiers` will give the above ICE itself if `_tiers` has data location `memory`.

Why does solc permit copying arrays to storage if the data location is `calldata` and it is part of a struct?

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

contract Counter {
struct DiscountTiers {
Discount[] discounts;
}

struct Discount {
uint256 discount;
uint256 expiry;
}

DiscountTiers tiers;
Discount[] discounts;

function setTiers(DiscountTiers calldata _tiers) public {
tiers = _tiers;
}

function getTiers() public view returns (Discount[] memory) {
return tiers.discounts;
}

function setDiscounts(Discount[] calldata _discounts) public {
discounts = _discounts;
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the Solidity PoC and the unimplemented-feature report at libsolidity/codegen/ArrayUtils.cpp:227, then run forge build with solc v0.8.24 to reproduce the difference between setTiers and setDiscounts. Done means direct memory or calldata array assignments to storage no longer report this ICE, while the struct case remains covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, solidity
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.