Merge pull request #12471 from ethereum/modifiers-control-flow-11483

Properly generated control flows for inherited modifiers
This commit is contained in:
Mathias L. Baumann
2022-01-06 13:39:50 +01:00
committed by GitHub
11 changed files with 109 additions and 62 deletions
@@ -1,5 +1,5 @@
contract C {
modifier revertIfNoReturn() {
modifier alwaysRevert() {
_;
revert();
}
@@ -9,10 +9,10 @@ contract C {
}
struct S { uint a; }
S s;
function f(bool flag) revertIfNoReturn() internal view {
function f(bool flag) alwaysRevert() internal view {
if (flag) s;
}
function g(bool flag) revertIfNoReturn() ifFlag(flag) internal view {
function g(bool flag) alwaysRevert() ifFlag(flag) internal view {
s;
}
@@ -0,0 +1,12 @@
contract A {
function f() mod internal returns (uint[] storage) {
revert();
}
function g() mod internal returns (uint[] storage) {
}
modifier mod() virtual {
_;
}
}
// ----
// TypeError 3464: (118-132): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,17 @@
contract A {
function f() mod internal returns (uint[] storage) {
}
modifier mod() virtual {
revert();
_;
}
}
contract B is A {
modifier mod() override { _; }
function g() public {
f()[0] = 42;
}
}
// ----
// Warning 5740: (65-69): Unreachable code.
// TypeError 3464: (49-63): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
@@ -1,5 +1,5 @@
contract C {
modifier revertIfNoReturn() {
modifier callAndRevert() {
_;
revert();
}
@@ -13,10 +13,10 @@ contract C {
return s;
}
function g(bool flag) ifFlag(flag) revertIfNoReturn() internal view returns(S storage) {
function g(bool flag) ifFlag(flag) callAndRevert() internal view returns(S storage) {
return s;
}
}
// ----
// TypeError 3464: (249-258): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
// TypeError 3464: (367-376): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
// TypeError 3464: (246-255): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
// TypeError 3464: (361-370): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
@@ -1,5 +1,5 @@
contract C {
modifier revertIfNoReturn() {
modifier callAndRevert() {
_;
revert();
}
@@ -9,10 +9,10 @@ contract C {
}
struct S { uint a; }
S s;
function f(bool flag) revertIfNoReturn() internal view returns(S storage) {
function f(bool flag) callAndRevert() internal view returns(S storage) {
if (flag) return s;
}
function g(bool flag) revertIfNoReturn() ifFlag(flag) internal view returns(S storage) {
function g(bool flag) callAndRevert() ifFlag(flag) internal view returns(S storage) {
return s;
}