foundry
foundry copied to clipboard
bug(forge): no-effect statements on the stack are not ignored in the coverage report
Component
Forge
Have you ensured that all of these are up to date?
- [X] Foundry
- [X] Foundryup
What version of Foundry are you on?
forge 0.2.0 (249538f 2023-02-08T00:12:05.805004Z)
What command(s) is the bug in?
forge coverage
Operating System
macOS (Apple Silicon)
Describe the bug
The forge coverage
command does not ignore no-effect statements for unused basic type conversions.
Just like #4310, I think that the priority for this issue should be set very high, because it may affect lot of Foundry users.
Reproduction Steps
Take the following contract:
contract Foo {
function coverMe() external pure returns (bool) {
uint256(1);
return true;
}
}
And the following test:
contract FooTest is Test {
Foo internal foo = new Foo();
function test_CoverMe() external {
bool result = foo.coverMe();
assertTrue(result);
}
}
Now, run forge coverage
. You will get this report:
[⠊] Compiling...
[⠢] Compiling 5 files with 0.8.18
[⠆] Solc 0.8.18 finished in 147.16ms
Compiler run successful (with warnings)
warning[6133]: Warning: Statement has no effect.
--> src/Foo.sol:6:9:
|
6 | uint256(1);
| ^^^^^^^^^^
Analysing contracts...
Running tests...
| File | % Lines | % Statements | % Branches | % Funcs |
|-------------|--------------|--------------|---------------|---------------|
| src/Foo.sol | 50.00% (1/2) | 50.00% (1/2) | 100.00% (0/0) | 100.00% (1/1) |
| Total | 50.00% (1/2) | 50.00% (1/2) | 100.00% (0/0) | 100.00% (1/1) |
Notice that the statement coverage is 50% instead of 100%, even if the no-effect is technically covered as part of the execution of the coverMe
function.
Now, do this - remove the uint256(1)
expression, and the branch coverage will increase to 100%:
| File | % Lines | % Statements | % Branches | % Funcs |
|-------------|---------------|---------------|---------------|---------------|
| src/Foo.sol | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
| Total | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
It follows that Forge does not currently ignore "no-effect statements" (as they are called by Solidity, see compiler output above).
Based on my research, this bug applies only to unused type conversion expressions on the stack. Changing the expression to smth like address(this)
or address(0xcafe)
or even bool(true)
will trigger the same 50% statement coverage report. However, interestingly enough, this bug does not apply to memory vars, i.e. changing the expression to string("")
will generate a 100% coverage report.