mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Extended test-coverage for storage declaration
This commit is contained in:
parent
79387b2ada
commit
aec0ae8ec1
@ -0,0 +1,38 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for {} eq(0,0) { c_slot := s_slot } {}
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for {} eq(0,1) { c_slot := s_slot } {}
|
||||
}
|
||||
c;
|
||||
}
|
||||
function h() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for {} eq(0,0) {} { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
function i() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for {} eq(0,1) {} { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (189-190): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (340-341): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (491-492): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (642-643): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
|
@ -0,0 +1,19 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for { c_slot := s_slot } iszero(0) {} {}
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
for { c_slot := s_slot } iszero(1) {} {}
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
if flag { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (188-189): This variable is of storage pointer type and can be accessed 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 {
|
||||
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
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure {
|
||||
S storage c;
|
||||
// this could be allowed, but currently control flow for functions is not analysed
|
||||
assembly {
|
||||
function f() { revert(0, 0) }
|
||||
f()
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (287-288): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
c_slot := s_slot
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,33 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(uint256 a) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch flag
|
||||
case 0 { c_slot := s_slot }
|
||||
case 1 { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
function h(uint256 a) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { c_slot := s_slot }
|
||||
default { return(0,0) }
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (208-209): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (421-422): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,31 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(uint256 a) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch a
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch flag
|
||||
case 0 { c_slot := s_slot }
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
function h(uint256 a) internal pure {
|
||||
S storage c;
|
||||
assembly {
|
||||
switch a
|
||||
case 0 { revert(0, 0) }
|
||||
default { c_slot := s_slot }
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,66 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
break;
|
||||
c = s;
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
if (s.f) {
|
||||
continue;
|
||||
c = s;
|
||||
}
|
||||
else {
|
||||
}
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
function h() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
if (s.f) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
c = s;
|
||||
}
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
function i() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
if (s.f) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
c = s;
|
||||
}
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
function j() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
continue;
|
||||
c = s;
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (184-185): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// Warning: (145-150): Unreachable code.
|
||||
// Warning: (168-173): Unreachable code.
|
||||
// TypeError: (411-412): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// Warning: (325-330): Unreachable code.
|
||||
// TypeError: (635-636): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (862-863): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (1011-1012): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// Warning: (972-977): Unreachable code.
|
@ -0,0 +1,44 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
do {} while((c = s).f);
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
do { c = s; } while(false);
|
||||
c;
|
||||
}
|
||||
function h() internal view {
|
||||
S storage c;
|
||||
c = s;
|
||||
do {} while(false);
|
||||
c;
|
||||
}
|
||||
function i() internal view {
|
||||
S storage c;
|
||||
do {} while(false);
|
||||
c = s;
|
||||
c;
|
||||
}
|
||||
function j() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
c = s;
|
||||
break;
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
function k() internal view {
|
||||
S storage c;
|
||||
do {
|
||||
c = s;
|
||||
continue;
|
||||
} while(false);
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (606-611): Unreachable code.
|
@ -0,0 +1,20 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
for(;; c = s) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
for(;;) {
|
||||
c = s;
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
//TypeError: (143-144): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (261-262): 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 {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
for(c = s;;) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
for(; (c = s).f;) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,22 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
else
|
||||
{
|
||||
if (!flag) c = s;
|
||||
else s.f = true;
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (138-139): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (330-331): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,39 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal view {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
else c = s;
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal view {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
else { c = s; }
|
||||
c;
|
||||
}
|
||||
function h(bool flag) internal view {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
else
|
||||
{
|
||||
if (!flag) c = s;
|
||||
else c = s;
|
||||
}
|
||||
c;
|
||||
}
|
||||
function i() internal view {
|
||||
S storage c;
|
||||
if ((c = s).f) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
function j() internal view {
|
||||
S storage c;
|
||||
if ((c = s).f && !(c = s).f) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,20 @@
|
||||
contract C {
|
||||
modifier revertIfNoReturn() {
|
||||
_;
|
||||
revert();
|
||||
}
|
||||
modifier ifFlag(bool flag) {
|
||||
if (flag)
|
||||
_;
|
||||
}
|
||||
struct S { uint a; }
|
||||
S s;
|
||||
function f(bool flag) revertIfNoReturn() internal view {
|
||||
if (flag) s;
|
||||
}
|
||||
function g(bool flag) revertIfNoReturn() ifFlag(flag) internal view {
|
||||
s;
|
||||
}
|
||||
|
||||
}
|
||||
// ----
|
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function g(bool flag) internal view {
|
||||
S storage c;
|
||||
if (flag) c = s;
|
||||
else revert();
|
||||
s;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,24 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
false && (c = s).f;
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
true || (c = s).f;
|
||||
c;
|
||||
}
|
||||
function h() internal view {
|
||||
S storage c;
|
||||
// expect error, although this is always fine
|
||||
true && (false || (c = s).f);
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (137-138): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (235-236): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (398-399): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
(c = s).f && false;
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
(c = s).f || true;
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal pure {}
|
||||
function g() internal view { s; }
|
||||
function h() internal view {
|
||||
S storage c;
|
||||
c = s;
|
||||
c;
|
||||
}
|
||||
function i() internal view {
|
||||
S storage c;
|
||||
(c) = s;
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal view {
|
||||
S storage c;
|
||||
flag ? (c = s).f : false;
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal view {
|
||||
S storage c;
|
||||
flag ? false : (c = s).f;
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (152-153): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (266-267): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,20 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f(bool flag) internal view {
|
||||
S storage c;
|
||||
flag ? c = s : c = s;
|
||||
c;
|
||||
}
|
||||
function g(bool flag) internal view {
|
||||
S storage c;
|
||||
flag ? c = s : (c = s);
|
||||
c;
|
||||
}
|
||||
function h(bool flag) internal view {
|
||||
S storage c;
|
||||
flag ? (c = s).f : (c = s).f;
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,42 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function ext() external {}
|
||||
function f() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { }
|
||||
catch (bytes memory) { r = s; }
|
||||
r;
|
||||
}
|
||||
function g() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { r = s; }
|
||||
catch (bytes memory) { }
|
||||
r;
|
||||
}
|
||||
function h() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() {}
|
||||
catch Error (string memory) { r = s; }
|
||||
catch (bytes memory) { r = s; }
|
||||
r;
|
||||
}
|
||||
function i() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { r = s; }
|
||||
catch (bytes memory) { r; }
|
||||
r = s;
|
||||
r;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// TypeError: (206-207): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (343-344): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (526-527): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError: (653-654): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,30 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function ext() external { }
|
||||
function f() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { r = s; }
|
||||
catch (bytes memory) { r = s; }
|
||||
r;
|
||||
}
|
||||
function g() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { r = s; }
|
||||
catch Error (string memory) { r = s; }
|
||||
catch (bytes memory) { r = s; }
|
||||
r;
|
||||
}
|
||||
function h() internal
|
||||
{
|
||||
S storage r;
|
||||
try this.ext() { }
|
||||
catch (bytes memory) { }
|
||||
r = s;
|
||||
r;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view returns (S storage, uint) {
|
||||
return (s,2);
|
||||
}
|
||||
function g() internal view {
|
||||
uint a;
|
||||
S storage c;
|
||||
(c, a) = f();
|
||||
c;
|
||||
}
|
||||
function h() internal view {
|
||||
(s, s);
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
while(false) {
|
||||
c = s;
|
||||
}
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (161-162): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,25 @@
|
||||
contract C {
|
||||
struct S { bool f; }
|
||||
S s;
|
||||
function f() internal view {
|
||||
S storage c;
|
||||
while((c = s).f) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
function g() internal view {
|
||||
S storage c;
|
||||
c = s;
|
||||
while(false) {
|
||||
}
|
||||
c;
|
||||
}
|
||||
function h() internal view {
|
||||
S storage c;
|
||||
while(false) {
|
||||
}
|
||||
c = s;
|
||||
c;
|
||||
}
|
||||
}
|
||||
// ----
|
Loading…
Reference in New Issue
Block a user