Check for circular constants across contracts.

This commit is contained in:
chriseth
2020-10-08 18:56:17 +02:00
parent c4d8b4fa0e
commit 21dee1c8ba
3 changed files with 36 additions and 10 deletions
+27 -10
View File
@@ -38,6 +38,13 @@ bool PostTypeChecker::check(ASTNode const& _astRoot)
return Error::containsOnlyWarnings(m_errorReporter.errors());
}
bool PostTypeChecker::finalize()
{
for (auto& checker: m_checkers)
checker->finalize();
return Error::containsOnlyWarnings(m_errorReporter.errors());
}
bool PostTypeChecker::visit(ContractDefinition const& _contractDefinition)
{
return callVisit(_contractDefinition);
@@ -83,6 +90,11 @@ bool PostTypeChecker::visit(Identifier const& _identifier)
return callVisit(_identifier);
}
bool PostTypeChecker::visit(MemberAccess const& _memberAccess)
{
return callVisit(_memberAccess);
}
bool PostTypeChecker::visit(StructDefinition const& _struct)
{
return callVisit(_struct);
@@ -110,14 +122,7 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker
ConstStateVarCircularReferenceChecker(ErrorReporter& _errorReporter):
Checker(_errorReporter) {}
bool visit(ContractDefinition const&) override
{
solAssert(!m_currentConstVariable, "");
solAssert(m_constVariableDependencies.empty(), "");
return true;
}
void endVisit(ContractDefinition const&) override
void finalize() override
{
solAssert(!m_currentConstVariable, "");
for (auto declaration: m_constVariables)
@@ -128,9 +133,12 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker
"The value of the constant " + declaration->name() +
" has a cyclic dependency via " + identifier->name() + "."
);
}
m_constVariables.clear();
m_constVariableDependencies.clear();
bool visit(ContractDefinition const&) override
{
solAssert(!m_currentConstVariable, "");
return true;
}
bool visit(VariableDeclaration const& _variable) override
@@ -162,6 +170,15 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker
return true;
}
bool visit(MemberAccess const& _memberAccess) override
{
if (m_currentConstVariable)
if (auto var = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
if (var->isConstant())
m_constVariableDependencies[m_currentConstVariable].insert(var);
return true;
}
VariableDeclaration const* findCycle(VariableDeclaration const& _startingFrom)
{
auto visitor = [&](VariableDeclaration const& _variable, util::CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)
+7
View File
@@ -54,6 +54,9 @@ public:
{
Checker(langutil::ErrorReporter& _errorReporter):
m_errorReporter(_errorReporter) {}
/// Called after all source units have been visited.
virtual void finalize() {}
protected:
langutil::ErrorReporter& m_errorReporter;
};
@@ -63,6 +66,9 @@ public:
bool check(ASTNode const& _astRoot);
/// Called after all source units have been visited.
bool finalize();
private:
bool visit(ContractDefinition const& _contract) override;
void endVisit(ContractDefinition const& _contract) override;
@@ -77,6 +83,7 @@ private:
bool visit(FunctionCall const& _functionCall) override;
bool visit(Identifier const& _identifier) override;
bool visit(MemberAccess const& _identifier) override;
bool visit(StructDefinition const& _struct) override;
void endVisit(StructDefinition const& _struct) override;