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 <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <boost/range/adaptor/reversed.hpp>
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
#include <libsolidity/Utils.h>
|
#include <libsolidity/Utils.h>
|
||||||
#include <libsolidity/AST.h>
|
#include <libsolidity/AST.h>
|
||||||
@ -434,23 +435,29 @@ void StructDefinition::checkMemberTypes() const
|
|||||||
|
|
||||||
void StructDefinition::checkRecursion() const
|
void StructDefinition::checkRecursion() const
|
||||||
{
|
{
|
||||||
set<StructDefinition const*> definitionsSeen;
|
using StructPointer = StructDefinition const*;
|
||||||
vector<StructDefinition const*> queue = {this};
|
using StructPointersSet = set<StructPointer>;
|
||||||
while (!queue.empty())
|
function<void(StructPointer,StructPointersSet const&)> check = [&](StructPointer _struct, StructPointersSet const& _parents)
|
||||||
{
|
{
|
||||||
StructDefinition const* def = queue.back();
|
if (_parents.count(_struct))
|
||||||
queue.pop_back();
|
BOOST_THROW_EXCEPTION(
|
||||||
if (definitionsSeen.count(def))
|
ParserError() <<
|
||||||
BOOST_THROW_EXCEPTION(ParserError() << errinfo_sourceLocation(def->getLocation())
|
errinfo_sourceLocation(_struct->getLocation()) <<
|
||||||
<< errinfo_comment("Recursive struct definition."));
|
errinfo_comment("Recursive struct definition.")
|
||||||
definitionsSeen.insert(def);
|
);
|
||||||
for (ASTPointer<VariableDeclaration> const& member: def->getMembers())
|
set<StructDefinition const*> parents = _parents;
|
||||||
|
parents.insert(_struct);
|
||||||
|
for (ASTPointer<VariableDeclaration> const& member: _struct->getMembers())
|
||||||
if (member->getType()->getCategory() == Type::Category::Struct)
|
if (member->getType()->getCategory() == Type::Category::Struct)
|
||||||
{
|
{
|
||||||
UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->getTypeName());
|
auto const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->getTypeName());
|
||||||
queue.push_back(&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()));
|
check(
|
||||||
|
&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()),
|
||||||
|
parents
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
check(this, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer EnumDefinition::getType(ContractDefinition const*) const
|
TypePointer EnumDefinition::getType(ContractDefinition const*) const
|
||||||
|
Loading…
Reference in New Issue
Block a user