mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Check for circular constants across contracts.
This commit is contained in:
parent
c4d8b4fa0e
commit
21dee1c8ba
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -387,6 +387,8 @@ bool CompilerStack::analyze()
|
||||
for (Source const* source: m_sourceOrder)
|
||||
if (source->ast && !postTypeChecker.check(*source->ast))
|
||||
noErrors = false;
|
||||
if (!postTypeChecker.finalize())
|
||||
noErrors = false;
|
||||
}
|
||||
|
||||
// Check that immutable variables are never read in c'tors and assigned
|
||||
|
Loading…
Reference in New Issue
Block a user