aboutsummaryrefslogtreecommitdiffstats
path: root/AST.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-18 22:35:25 +0800
committerchriseth <c@ethdev.com>2015-06-18 22:37:06 +0800
commitee520f602263ba0fc70d51f3317d98a59e115ae3 (patch)
treeb17bc74786cb0e7d9c79c24a16eae075c36bbeb8 /AST.cpp
parent1ff8dbebab1aa450e6800fd188e21aa7944b898c (diff)
downloaddexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar.gz
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar.bz2
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar.lz
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar.xz
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.tar.zst
dexon-solidity-ee520f602263ba0fc70d51f3317d98a59e115ae3.zip
Fix and test for not really recursive structs.
Fixes #2223.
Diffstat (limited to 'AST.cpp')
-rw-r--r--AST.cpp33
1 files changed, 20 insertions, 13 deletions
diff --git a/AST.cpp b/AST.cpp
index 6d6a13cf..7333c024 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -21,6 +21,7 @@
*/
#include <algorithm>
+#include <functional>
#include <boost/range/adaptor/reversed.hpp>
#include <libsolidity/Utils.h>
#include <libsolidity/AST.h>
@@ -434,23 +435,29 @@ void StructDefinition::checkMemberTypes() const
void StructDefinition::checkRecursion() const
{
- set<StructDefinition const*> definitionsSeen;
- vector<StructDefinition const*> queue = {this};
- while (!queue.empty())
+ using StructPointer = StructDefinition const*;
+ using StructPointersSet = set<StructPointer>;
+ function<void(StructPointer,StructPointersSet const&)> check = [&](StructPointer _struct, StructPointersSet const& _parents)
{
- StructDefinition const* def = queue.back();
- queue.pop_back();
- if (definitionsSeen.count(def))
- BOOST_THROW_EXCEPTION(ParserError() << errinfo_sourceLocation(def->getLocation())
- << errinfo_comment("Recursive struct definition."));
- definitionsSeen.insert(def);
- for (ASTPointer<VariableDeclaration> const& member: def->getMembers())
+ if (_parents.count(_struct))
+ BOOST_THROW_EXCEPTION(
+ ParserError() <<
+ errinfo_sourceLocation(_struct->getLocation()) <<
+ errinfo_comment("Recursive struct definition.")
+ );
+ set<StructDefinition const*> parents = _parents;
+ parents.insert(_struct);
+ for (ASTPointer<VariableDeclaration> const& member: _struct->getMembers())
if (member->getType()->getCategory() == Type::Category::Struct)
{
- UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->getTypeName());
- queue.push_back(&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()));
+ auto const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->getTypeName());
+ check(
+ &dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()),
+ parents
+ );
}
- }
+ };
+ check(this, {});
}
TypePointer EnumDefinition::getType(ContractDefinition const*) const