mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Control flow analysis for inline assembly.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
function f() {
|
||||
// Make sure this doesn't trigger the unimplemented assertion in the control flow builder.
|
||||
leave
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
// Make sure this doesn't trigger the unimplemented assertion in the control flow builder.
|
||||
leave
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// SyntaxError: (178-183): Keyword "leave" can only be used inside a function.
|
||||
@@ -0,0 +1,29 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for {} eq(0,0) { c_slot := s_slot } {}
|
||||
}
|
||||
}
|
||||
function g() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for {} eq(0,1) { c_slot := s_slot } {}
|
||||
}
|
||||
}
|
||||
function h() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for {} eq(0,0) {} { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
function i() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for {} eq(0,1) {} { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (228-239): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (369-380): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (510-521): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
@@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for { c_slot := s_slot } iszero(0) {} {}
|
||||
}
|
||||
}
|
||||
function g() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
for { c_slot := s_slot } iszero(1) {} {}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
if flag { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure returns (S storage c) {
|
||||
// this should warn about unreachable code, but currently function flow is ignored
|
||||
assembly {
|
||||
function f() { return(0, 0) }
|
||||
f()
|
||||
c_slot := s_slot
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure returns (S storage c) {
|
||||
// this could be allowed, but currently control flow for functions is not analysed
|
||||
assembly {
|
||||
function f() { revert(0, 0) }
|
||||
f()
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
@@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure returns (S storage c) {
|
||||
assembly {
|
||||
c_slot := s_slot
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,27 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(uint256 a) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
function g(bool flag) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch flag
|
||||
case 0 { c_slot := s_slot }
|
||||
case 1 { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
function h(uint256 a) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { c_slot := s_slot }
|
||||
default { return(0,0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (256-267): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.
|
||||
@@ -0,0 +1,25 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(uint256 a) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch a
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
function g(bool flag) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch flag
|
||||
case 0 { c_slot := s_slot }
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
function h(uint256 a) internal pure returns (S storage c) {
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { revert(0, 0) }
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -6,4 +6,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (92-116): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (107-113): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
revert(0, 0)
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
function g() public pure {
|
||||
assembly {
|
||||
revert(0, 0)
|
||||
}
|
||||
revert();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (100-112): Unreachable code.
|
||||
// Warning: (222-230): Unreachable code.
|
||||
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
for { let a := 0} lt(a,1) { a := add(a, 1) } {
|
||||
break
|
||||
let b := 42
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (103-117): Unreachable code.
|
||||
// Warning: (160-171): Unreachable code.
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
for { let a := 0} lt(a,1) { a := add(a, 1) } {
|
||||
continue
|
||||
let b := 42
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (163-174): Unreachable code.
|
||||
@@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function f(uint256 y) public pure returns (uint256 x) {
|
||||
assembly {
|
||||
return(0, 0)
|
||||
x := y
|
||||
}
|
||||
}
|
||||
function g(uint256 y) public pure returns (uint256 x) {
|
||||
assembly {
|
||||
return(0, 0)
|
||||
}
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (129-135): Unreachable code.
|
||||
// Warning: (274-279): Unreachable code.
|
||||
@@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function f(uint256 y) public pure returns (uint256 x) {
|
||||
assembly {
|
||||
revert(0, 0)
|
||||
x := y
|
||||
}
|
||||
}
|
||||
function g(uint256 y) public pure returns (uint256 x) {
|
||||
assembly {
|
||||
revert(0, 0)
|
||||
}
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (129-135): Unreachable code.
|
||||
// Warning: (274-279): Unreachable code.
|
||||
@@ -539,7 +539,7 @@ BOOST_AUTO_TEST_CASE(builtins_analysis)
|
||||
{
|
||||
return _name == "builtin"_yulstring ? &f : nullptr;
|
||||
}
|
||||
BuiltinFunction f{"builtin"_yulstring, vector<Type>(2), vector<Type>(3), {}};
|
||||
BuiltinFunction f{"builtin"_yulstring, vector<Type>(2), vector<Type>(3), {}, {}};
|
||||
};
|
||||
|
||||
SimpleDialect dialect;
|
||||
|
||||
Reference in New Issue
Block a user