Fixed recursive check in structureSizeEstimate

This commit is contained in:
a3d4 2020-06-11 15:52:36 +02:00
parent ea46636ad2
commit c2e1273ff4
9 changed files with 34 additions and 21 deletions

View File

@ -346,24 +346,21 @@ bigint StaticAnalyzer::structureSizeEstimate(Type const& _type, set<StructDefini
case Type::Category::Array: case Type::Category::Array:
{ {
auto const& t = dynamic_cast<ArrayType const&>(_type); auto const& t = dynamic_cast<ArrayType const&>(_type);
return structureSizeEstimate(*t.baseType(), _structsSeen) * (t.isDynamicallySized() ? 1 : t.length()); if (!t.isDynamicallySized())
return structureSizeEstimate(*t.baseType(), _structsSeen) * t.length();
break;
} }
case Type::Category::Struct: case Type::Category::Struct:
{ {
auto const& t = dynamic_cast<StructType const&>(_type); auto const& t = dynamic_cast<StructType const&>(_type);
solAssert(!_structsSeen.count(&t.structDefinition()), "Recursive struct.");
bigint size = 1; bigint size = 1;
if (!_structsSeen.count(&t.structDefinition())) _structsSeen.insert(&t.structDefinition());
{ for (auto const& m: t.members(nullptr))
_structsSeen.insert(&t.structDefinition()); size += structureSizeEstimate(*m.type, _structsSeen);
for (auto const& m: t.members(nullptr)) _structsSeen.erase(&t.structDefinition());
size += structureSizeEstimate(*m.type, _structsSeen);
}
return size; return size;
} }
case Type::Category::Mapping:
{
return structureSizeEstimate(*dynamic_cast<MappingType const&>(_type).valueType(), _structsSeen);
}
default: default:
break; break;
} }

View File

@ -0,0 +1,4 @@
contract C {
mapping(uint => uint[2**100]) x;
}
// ----

View File

@ -0,0 +1,4 @@
contract C {
uint[200][200][2**30][][2**30] x;
}
// ----

View File

@ -0,0 +1,18 @@
contract C {
struct P0 { uint256[2**63] x; }
struct S0 {
P0[2**62] y;
P0 x;
}
S0 s0;
struct P1 { uint256[2**63] x; }
struct S1 {
P1 x;
P1[2**62] y;
}
S1 s1;
}
// ----
// Warning 3408: (110-115): Variable covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
// Warning 3408: (215-220): Variable covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.

View File

@ -1,5 +0,0 @@
contract C {
uint[200][200][2**30][][2**30] x;
}
// ----
// Warning 3408: (17-49): Variable covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.

View File

@ -1,5 +0,0 @@
contract C {
mapping(uint => uint[2**100]) x;
}
// ----
// Warning 3408: (17-48): Variable covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.