Skip to content

Commit

Permalink
Mark member access to constants as pure and fix cross contract cyclic…
Browse files Browse the repository at this point in the history
… dependency check.
  • Loading branch information
ekpyron committed Apr 12, 2018
1 parent b6047e0 commit 9012398
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 14 deletions.
23 changes: 13 additions & 10 deletions libsolidity/analysis/PostTypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,13 @@ using namespace dev::solidity;


bool PostTypeChecker::check(ASTNode const& _astRoot)
{
_astRoot.accept(*this);
return Error::containsOnlyWarnings(m_errorReporter.errors());
}

bool PostTypeChecker::visit(ContractDefinition const&)
{
solAssert(!m_currentConstVariable, "");
solAssert(m_constVariables.empty(), "");
solAssert(m_constVariableDependencies.empty(), "");
return true;
}

void PostTypeChecker::endVisit(ContractDefinition const&)
{
_astRoot.accept(*this);

solAssert(!m_currentConstVariable, "");
for (auto declaration: m_constVariables)
if (auto identifier = findCycle(*declaration))
Expand All @@ -58,6 +51,7 @@ void PostTypeChecker::endVisit(ContractDefinition const&)

m_constVariables.clear();
m_constVariableDependencies.clear();
return Error::containsOnlyWarnings(m_errorReporter.errors());
}

bool PostTypeChecker::visit(VariableDeclaration const& _variable)
Expand Down Expand Up @@ -89,6 +83,15 @@ bool PostTypeChecker::visit(Identifier const& _identifier)
return true;
}

bool PostTypeChecker::visit(MemberAccess const &_memberAccess)
{
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* PostTypeChecker::findCycle(VariableDeclaration const& _startingFrom)
{
auto visitor = [&](VariableDeclaration const& _variable, CycleDetector<VariableDeclaration>& _cycleDetector)
Expand Down
4 changes: 1 addition & 3 deletions libsolidity/analysis/PostTypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ class PostTypeChecker: private ASTConstVisitor
/// Adds a new error to the list of errors.
void typeError(SourceLocation const& _location, std::string const& _description);

virtual bool visit(ContractDefinition const& _contract) override;
virtual void endVisit(ContractDefinition const& _contract) override;

virtual bool visit(VariableDeclaration const& _variable) override;
virtual void endVisit(VariableDeclaration const& _variable) override;

virtual bool visit(Identifier const& _identifier) override;
virtual bool visit(MemberAccess const& _memberAccess) override;

VariableDeclaration const* findCycle(VariableDeclaration const& _startingFrom);

Expand Down
4 changes: 4 additions & 0 deletions libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,10 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (tt->actualType()->category() == Type::Category::Enum)
annotation.isPure = true;

if (auto var = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
if (var->isConstant())
annotation.isPure = true;

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ contract B {
uint constant c = A.c;
}
// ----
// Some Error: This should fail with some error!
// TypeError: (17-38): The value of the constant c has a cyclic dependency via c.
// TypeError: (59-80): The value of the constant c has a cyclic dependency via c.

0 comments on commit 9012398

Please sign in to comment.