Skip to content

Commit 5725b61

Browse files
authored
Merge pull request #15900 from ethereum/fixStorageLayoutSpecifierErrorMsg
Report errors only for contracts that directly inherit from one with a specified storage layout
2 parents 1d26a83 + 2995f04 commit 5725b61

File tree

7 files changed

+48
-29
lines changed

7 files changed

+48
-29
lines changed

libsolidity/analysis/ContractLevelChecker.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <fmt/format.h>
3232

33+
#include <range/v3/algorithm/find_if.hpp>
3334
#include <range/v3/view/reverse.hpp>
3435

3536
using namespace solidity;
@@ -116,19 +117,22 @@ void ContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const&
116117
);
117118
}
118119

119-
for (auto const* ancestorContract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse)
120+
for (auto const& baseContractSpecifier: _contract.baseContracts())
120121
{
121-
if (*ancestorContract == _contract)
122-
continue;
123-
if (ancestorContract->storageLayoutSpecifier())
122+
auto const* baseContract = dynamic_cast<ContractDefinition const*>(
123+
baseContractSpecifier->name().annotation().referencedDeclaration
124+
);
125+
126+
solAssert(baseContract);
127+
if (baseContract->storageLayoutSpecifier())
124128
m_errorReporter.typeError(
125129
8894_error,
126-
_contract.location(),
130+
baseContractSpecifier->location(),
127131
SecondarySourceLocation().append(
128-
"Storage layout was already specified here.",
129-
ancestorContract->storageLayoutSpecifier()->location()
132+
"Custom storage layout defined here:",
133+
baseContract->storageLayoutSpecifier()->location()
130134
),
131-
"Storage layout can only be specified in the most derived contract."
135+
"Cannot inherit from a contract with a custom storage layout."
132136
);
133137
}
134138
}

test/cmdlineTests/storage_layout_already_defined_in_ancestor/err

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,9 @@
1-
Error: Storage layout can only be specified in the most derived contract.
2-
--> <stdin>:5:1:
1+
Error: Cannot inherit from a contract with a custom storage layout.
2+
--> <stdin>:5:15:
33
|
44
5 | contract B is A {}
5-
| ^^^^^^^^^^^^^^^^^^
6-
Note: Storage layout was already specified here.
7-
--> <stdin>:4:12:
8-
|
9-
4 | contract A layout at 0x1234 {}
10-
| ^^^^^^^^^^^^^^^^
11-
12-
Error: Storage layout can only be specified in the most derived contract.
13-
--> <stdin>:6:1:
14-
|
15-
6 | contract C layout at 0x1234 is B {}
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17-
Note: Storage layout was already specified here.
5+
| ^
6+
Note: Custom storage layout defined here:
187
--> <stdin>:4:12:
198
|
209
4 | contract A layout at 0x1234 {}

test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ contract B is A {}
44

55
contract C is B layout at 0xABCD {}
66
// ----
7-
// TypeError 8894: (32-50): Storage layout can only be specified in the most derived contract.
8-
// TypeError 8894: (52-87): Storage layout can only be specified in the most derived contract.
7+
// TypeError 8894: (46-47): Cannot inherit from a contract with a custom storage layout.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
==== Source: C ====
2+
import "M" as M;
3+
import "N" as N;
4+
5+
contract C is M.A, N.A layout at 0xABCD {}
6+
==== Source: M ====
7+
contract A layout at 0x1234 {}
8+
9+
==== Source: N ====
10+
contract A {}
11+
12+
// ----
13+
// TypeError 8894: (C:49-52): Cannot inherit from a contract with a custom storage layout.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
contract A layout at 1 {}
2+
contract B is A layout at 2 {}
3+
4+
contract C1 is B {}
5+
contract C2 is A, B {}
6+
contract C3 is B {}
7+
8+
contract D1 is C1 {}
9+
contract D2 is C2 {}
10+
contract D3 is C3 {}
11+
// ----
12+
// TypeError 8894: (40-41): Cannot inherit from a contract with a custom storage layout.
13+
// TypeError 8894: (73-74): Cannot inherit from a contract with a custom storage layout.
14+
// TypeError 8894: (93-94): Cannot inherit from a contract with a custom storage layout.
15+
// TypeError 8894: (96-97): Cannot inherit from a contract with a custom storage layout.
16+
// TypeError 8894: (116-117): Cannot inherit from a contract with a custom storage layout.

test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@ contract B is A {}
33
contract C is B {}
44
contract D is C {}
55
// ----
6-
// TypeError 8894: (27-45): Storage layout can only be specified in the most derived contract.
7-
// TypeError 8894: (46-64): Storage layout can only be specified in the most derived contract.
8-
// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract.
6+
// TypeError 8894: (41-42): Cannot inherit from a contract with a custom storage layout.

test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ contract B is A {}
33
contract C is B layout at 42 {}
44
contract D is C {}
55
// ----
6-
// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract.
6+
// TypeError 8894: (79-80): Cannot inherit from a contract with a custom storage layout.

0 commit comments

Comments
 (0)