Fix and test for not really recursive structs.

Fixes #2223.
This commit is contained in:
chriseth 2015-06-18 16:35:25 +02:00
parent 1ff8dbebab
commit ee520f6022

33
AST.cpp
View File

@ -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