aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-03-16 02:53:29 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-04-03 22:29:18 +0800
commiteb5b18e8145d7d3971c450ba220f322e5f66d45c (patch)
tree19efd096e8c7ac0761a3f38279c75ecf5fb1d273 /libsolidity/ast
parent5bdadff0d8a9c32745dd46aa639283718613efdc (diff)
downloaddexon-solidity-eb5b18e8145d7d3971c450ba220f322e5f66d45c.tar.gz
dexon-solidity-eb5b18e8145d7d3971c450ba220f322e5f66d45c.tar.zst
dexon-solidity-eb5b18e8145d7d3971c450ba220f322e5f66d45c.zip
Generalize cycle detection.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/Types.cpp22
1 files changed, 6 insertions, 16 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 42f6b5ca..ac1d3b01 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -28,6 +28,7 @@
#include <libdevcore/CommonData.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/UTF8.h>
+#include <libdevcore/Algorithms.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
@@ -1971,30 +1972,19 @@ bool StructType::recursive() const
{
if (!m_recursive.is_initialized())
{
- set<StructDefinition const*> structsSeen;
- set<StructDefinition const*> structsProcessed;
- function<bool(StructType const*)> check = [&](StructType const* t) -> bool
+ auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector)
{
- StructDefinition const* str = &t->structDefinition();
- if (structsProcessed.count(str))
- return false;
- if (structsSeen.count(str))
- return true;
- structsSeen.insert(str);
- for (ASTPointer<VariableDeclaration> const& variable: str->members())
+ for (ASTPointer<VariableDeclaration> const& variable: _struct.members())
{
Type const* memberType = variable->annotation().type.get();
while (dynamic_cast<ArrayType const*>(memberType))
memberType = dynamic_cast<ArrayType const*>(memberType)->baseType().get();
if (StructType const* innerStruct = dynamic_cast<StructType const*>(memberType))
- if (check(innerStruct))
- return true;
+ if (_cycleDetector.run(innerStruct->structDefinition()))
+ return;
}
- structsSeen.erase(str);
- structsProcessed.insert(str);
- return false;
};
- m_recursive = check(this);
+ m_recursive = (CycleDetector<StructDefinition>(visitor).run(structDefinition()) != nullptr);
}
return *m_recursive;
}