From ee520f602263ba0fc70d51f3317d98a59e115ae3 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 18 Jun 2015 16:35:25 +0200 Subject: Fix and test for not really recursive structs. Fixes #2223. --- AST.cpp | 33 ++++++++++++++++++++------------- 1 file 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 +#include #include #include #include @@ -434,23 +435,29 @@ void StructDefinition::checkMemberTypes() const void StructDefinition::checkRecursion() const { - set definitionsSeen; - vector queue = {this}; - while (!queue.empty()) + using StructPointer = StructDefinition const*; + using StructPointersSet = set; + function 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 const& member: def->getMembers()) + if (_parents.count(_struct)) + BOOST_THROW_EXCEPTION( + ParserError() << + errinfo_sourceLocation(_struct->getLocation()) << + errinfo_comment("Recursive struct definition.") + ); + set parents = _parents; + parents.insert(_struct); + for (ASTPointer const& member: _struct->getMembers()) if (member->getType()->getCategory() == Type::Category::Struct) { - UserDefinedTypeName const& typeName = dynamic_cast(*member->getTypeName()); - queue.push_back(&dynamic_cast(*typeName.getReferencedDeclaration())); + auto const& typeName = dynamic_cast(*member->getTypeName()); + check( + &dynamic_cast(*typeName.getReferencedDeclaration()), + parents + ); } - } + }; + check(this, {}); } TypePointer EnumDefinition::getType(ContractDefinition const*) const -- cgit v1.2.3