Fix detection of recursive structs.

This commit is contained in:
chriseth 2018-03-15 19:07:25 +01:00 committed by Alex Beregszaszi
parent c42caedec2
commit 5bdadff0d8
4 changed files with 36 additions and 0 deletions

View File

@ -16,6 +16,7 @@ Bugfixes:
* Commandline interface: Support ``--evm-version constantinople`` properly. * Commandline interface: Support ``--evm-version constantinople`` properly.
* DocString Parser: Fix error message for empty descriptions. * DocString Parser: Fix error message for empty descriptions.
* Standard JSON: Support ``constantinople`` as ``evmVersion`` properly. * Standard JSON: Support ``constantinople`` as ``evmVersion`` properly.
* Type Checker: Fix detection of recursive structs.
* Type System: Improve error message when attempting to shift by a fractional amount. * Type System: Improve error message when attempting to shift by a fractional amount.
* Type System: Make external library functions accessible. * Type System: Make external library functions accessible.
* Type System: Prevent encoding of weird types. * Type System: Prevent encoding of weird types.

View File

@ -1972,9 +1972,12 @@ bool StructType::recursive() const
if (!m_recursive.is_initialized()) if (!m_recursive.is_initialized())
{ {
set<StructDefinition const*> structsSeen; set<StructDefinition const*> structsSeen;
set<StructDefinition const*> structsProcessed;
function<bool(StructType const*)> check = [&](StructType const* t) -> bool function<bool(StructType const*)> check = [&](StructType const* t) -> bool
{ {
StructDefinition const* str = &t->structDefinition(); StructDefinition const* str = &t->structDefinition();
if (structsProcessed.count(str))
return false;
if (structsSeen.count(str)) if (structsSeen.count(str))
return true; return true;
structsSeen.insert(str); structsSeen.insert(str);
@ -1987,6 +1990,8 @@ bool StructType::recursive() const
if (check(innerStruct)) if (check(innerStruct))
return true; return true;
} }
structsSeen.erase(str);
structsProcessed.insert(str);
return false; return false;
}; };
m_recursive = check(this); m_recursive = check(this);

View File

@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
struct T { U u; V v; }
struct U { W w; }
struct V { W w; }
struct W { uint x; }
function f(T) public pure { }
}
// ----
// Warning: Experimental features are turned on. Do not use experimental features on live deployments.

View File

@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract TestContract
{
struct SubStruct {
uint256 id;
}
struct TestStruct {
SubStruct subStruct1;
SubStruct subStruct2;
}
function addTestStruct(TestStruct) public pure {}
}
// ----
// Warning: Experimental features are turned on. Do not use experimental features on live deployments.