argotorg / argotorg/solidity

use before assignment of calldata struct instance inside a function does not throw an error

Open
#15,483 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug :bug:
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
2d 19h
Merged PRs (30d)
29

Description

Description

The following program is a trivially correct one. I copy data from calldata to memory.

contract A {
  struct S {
    int a;
  }
  function f (S calldata s) public pure {
    S memory s3;
    s3 = s;
  }
}

Then I mutate this test program into the following:

contract A {
  struct S {
    int a;
  }
  function f (S calldata s) public pure {
    S calldata s2;
    S memory s3;
    s3 = s2; // fail: This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
  }
}

This test program causes an error, saying that This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.. This is understandable. calldata is used to receive data from other contracts. So the calldata in a function without initialization is empty and should be initialized first.

I continue the mutation by initializing s2 first like the below and it passed the compilation.

contract A {
  struct S {
    int a;
  }
  function f (S calldata s) public pure {
    S calldata s2 = s;
    S memory s3;
    s3 = s2; // pass
  }
}

Now I wonder if the compiler can find an incorrect initialization of a calldata slot. So I initialize the calldata slot with itself, an initialized calldata slot, to get the following program:

contract A {
  struct S {
    int a;
  }
  function f (S calldata s) public pure {
    S calldata s2;
    s2 = s2;
    S memory s3;
    s3 = s2; // pass
  }
}

Interestingly, the above test program does not trigger an expected error with message such as This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour. but passed the compilation.

Environment

  • Compiler version:0.8.28-develop.2024.9.30+commit.33b67f0a
  • Operating system: macos

Steps to Reproduce

Just compile the above programs and you will reproduce the compilation results.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test entry point is named. First compile the three Solidity examples with the reported compiler version and compare the diagnostics, then trace the compiler's handling of uninitialized calldata struct assignments and self-assignment. Done means the self-assignment case is rejected consistently with the direct uninitialized access case, with regression coverage for the examples.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.