mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
parent
1ff8dbebab
commit
ee520f6022
33
AST.cpp
33
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
|
||||
|
Loading…
Reference in New Issue
Block a user