diff options
author | chriseth <c@ethdev.com> | 2015-06-18 22:35:25 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-18 22:37:06 +0800 |
commit | ee520f602263ba0fc70d51f3317d98a59e115ae3 (patch) | |
tree | b17bc74786cb0e7d9c79c24a16eae075c36bbeb8 /AST.cpp | |
parent | 1ff8dbebab1aa450e6800fd188e21aa7944b898c (diff) | |
download | dexon-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.cpp | 33 |
1 files changed, 20 insertions, 13 deletions
@@ -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 |