Refactoring Declaration -> VariableDeclaration (more precise)

This commit is contained in:
Leonardo Alt 2018-06-12 10:58:24 +02:00
parent 48652c88af
commit 207d5859d1
4 changed files with 42 additions and 43 deletions

View File

@ -109,7 +109,7 @@ bool SMTChecker::visit(IfStatement const& _node)
checkBooleanNotConstant(_node.condition(), "Condition is always $VALUE."); checkBooleanNotConstant(_node.condition(), "Condition is always $VALUE.");
auto countersEndTrue = visitBranch(_node.trueStatement(), expr(_node.condition())); auto countersEndTrue = visitBranch(_node.trueStatement(), expr(_node.condition()));
vector<Declaration const*> touchedVariables = m_variableUsage->touchedVariables(_node.trueStatement()); vector<VariableDeclaration const*> touchedVariables = m_variableUsage->touchedVariables(_node.trueStatement());
decltype(countersEndTrue) countersEndFalse; decltype(countersEndTrue) countersEndFalse;
if (_node.falseStatement()) if (_node.falseStatement())
{ {
@ -229,10 +229,10 @@ void SMTChecker::endVisit(Assignment const& _assignment)
); );
else if (Identifier const* identifier = dynamic_cast<Identifier const*>(&_assignment.leftHandSide())) else if (Identifier const* identifier = dynamic_cast<Identifier const*>(&_assignment.leftHandSide()))
{ {
Declaration const* decl = identifier->annotation().referencedDeclaration; VariableDeclaration const& decl = dynamic_cast<VariableDeclaration const&>(*identifier->annotation().referencedDeclaration);
if (knownVariable(*decl)) if (knownVariable(decl))
{ {
assignment(*decl, _assignment.rightHandSide(), _assignment.location()); assignment(decl, _assignment.rightHandSide(), _assignment.location());
defineExpr(_assignment, expr(_assignment.rightHandSide())); defineExpr(_assignment, expr(_assignment.rightHandSide()));
} }
else else
@ -295,12 +295,12 @@ void SMTChecker::endVisit(UnaryOperation const& _op)
solAssert(_op.subExpression().annotation().lValueRequested, ""); solAssert(_op.subExpression().annotation().lValueRequested, "");
if (Identifier const* identifier = dynamic_cast<Identifier const*>(&_op.subExpression())) if (Identifier const* identifier = dynamic_cast<Identifier const*>(&_op.subExpression()))
{ {
Declaration const* decl = identifier->annotation().referencedDeclaration; VariableDeclaration const& decl = dynamic_cast<VariableDeclaration const&>(*identifier->annotation().referencedDeclaration);
if (knownVariable(*decl)) if (knownVariable(decl))
{ {
auto innerValue = currentValue(*decl); auto innerValue = currentValue(decl);
auto newValue = _op.getOperator() == Token::Inc ? innerValue + 1 : innerValue - 1; auto newValue = _op.getOperator() == Token::Inc ? innerValue + 1 : innerValue - 1;
assignment(*decl, newValue, _op.location()); assignment(decl, newValue, _op.location());
defineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue); defineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue);
} }
else else
@ -382,14 +382,15 @@ void SMTChecker::endVisit(FunctionCall const& _funCall)
void SMTChecker::endVisit(Identifier const& _identifier) void SMTChecker::endVisit(Identifier const& _identifier)
{ {
Declaration const* decl = _identifier.annotation().referencedDeclaration;
solAssert(decl, "");
if (_identifier.annotation().lValueRequested) if (_identifier.annotation().lValueRequested)
{ {
// Will be translated as part of the node that requested the lvalue. // Will be translated as part of the node that requested the lvalue.
} }
else if (SSAVariable::isSupportedType(_identifier.annotation().type->category())) else if (SSAVariable::isSupportedType(_identifier.annotation().type->category()))
defineExpr(_identifier, currentValue(*decl)); {
VariableDeclaration const& decl = dynamic_cast<VariableDeclaration const&>(*(_identifier.annotation().referencedDeclaration));
defineExpr(_identifier, currentValue(decl));
}
else if (FunctionType const* fun = dynamic_cast<FunctionType const*>(_identifier.annotation().type.get())) else if (FunctionType const* fun = dynamic_cast<FunctionType const*>(_identifier.annotation().type.get()))
{ {
if (fun->kind() == FunctionType::Kind::Assert || fun->kind() == FunctionType::Kind::Require) if (fun->kind() == FunctionType::Kind::Assert || fun->kind() == FunctionType::Kind::Require)
@ -529,12 +530,12 @@ smt::Expression SMTChecker::division(smt::Expression _left, smt::Expression _rig
return _left / _right; return _left / _right;
} }
void SMTChecker::assignment(Declaration const& _variable, Expression const& _value, SourceLocation const& _location) void SMTChecker::assignment(VariableDeclaration const& _variable, Expression const& _value, SourceLocation const& _location)
{ {
assignment(_variable, expr(_value), _location); assignment(_variable, expr(_value), _location);
} }
void SMTChecker::assignment(Declaration const& _variable, smt::Expression const& _value, SourceLocation const& _location) void SMTChecker::assignment(VariableDeclaration const& _variable, smt::Expression const& _value, SourceLocation const& _location)
{ {
TypePointer type = _variable.type(); TypePointer type = _variable.type();
if (auto const* intType = dynamic_cast<IntegerType const*>(type.get())) if (auto const* intType = dynamic_cast<IntegerType const*>(type.get()))
@ -729,8 +730,7 @@ void SMTChecker::resetStateVariables()
{ {
for (auto const& variable: m_variables) for (auto const& variable: m_variables)
{ {
VariableDeclaration const& _decl = dynamic_cast<VariableDeclaration const&>(*variable.first); if (variable.first->isStateVariable())
if (_decl.isStateVariable())
{ {
newValue(*variable.first); newValue(*variable.first);
setUnknownValue(*variable.first); setUnknownValue(*variable.first);
@ -738,7 +738,7 @@ void SMTChecker::resetStateVariables()
} }
} }
void SMTChecker::resetVariables(vector<Declaration const*> _variables) void SMTChecker::resetVariables(vector<VariableDeclaration const*> _variables)
{ {
for (auto const* decl: _variables) for (auto const* decl: _variables)
{ {
@ -747,9 +747,9 @@ void SMTChecker::resetVariables(vector<Declaration const*> _variables)
} }
} }
void SMTChecker::mergeVariables(vector<Declaration const*> const& _variables, smt::Expression const& _condition, VariableSequenceCounters const& _countersEndTrue, VariableSequenceCounters const& _countersEndFalse) void SMTChecker::mergeVariables(vector<VariableDeclaration const*> const& _variables, smt::Expression const& _condition, VariableSequenceCounters const& _countersEndTrue, VariableSequenceCounters const& _countersEndFalse)
{ {
set<Declaration const*> uniqueVars(_variables.begin(), _variables.end()); set<VariableDeclaration const*> uniqueVars(_variables.begin(), _variables.end());
for (auto const* decl: uniqueVars) for (auto const* decl: uniqueVars)
{ {
int trueCounter = _countersEndTrue.at(decl).index(); int trueCounter = _countersEndTrue.at(decl).index();
@ -786,37 +786,37 @@ string SMTChecker::uniqueSymbol(Expression const& _expr)
return "expr_" + to_string(_expr.id()); return "expr_" + to_string(_expr.id());
} }
bool SMTChecker::knownVariable(Declaration const& _decl) bool SMTChecker::knownVariable(VariableDeclaration const& _decl)
{ {
return m_variables.count(&_decl); return m_variables.count(&_decl);
} }
smt::Expression SMTChecker::currentValue(Declaration const& _decl) smt::Expression SMTChecker::currentValue(VariableDeclaration const& _decl)
{ {
solAssert(knownVariable(_decl), ""); solAssert(knownVariable(_decl), "");
return m_variables.at(&_decl)(); return m_variables.at(&_decl)();
} }
smt::Expression SMTChecker::valueAtSequence(Declaration const& _decl, int _sequence) smt::Expression SMTChecker::valueAtSequence(VariableDeclaration const& _decl, int _sequence)
{ {
solAssert(knownVariable(_decl), ""); solAssert(knownVariable(_decl), "");
return m_variables.at(&_decl)(_sequence); return m_variables.at(&_decl)(_sequence);
} }
smt::Expression SMTChecker::newValue(Declaration const& _decl) smt::Expression SMTChecker::newValue(VariableDeclaration const& _decl)
{ {
solAssert(knownVariable(_decl), ""); solAssert(knownVariable(_decl), "");
++m_variables.at(&_decl); ++m_variables.at(&_decl);
return m_variables.at(&_decl)(); return m_variables.at(&_decl)();
} }
void SMTChecker::setZeroValue(Declaration const& _decl) void SMTChecker::setZeroValue(VariableDeclaration const& _decl)
{ {
solAssert(knownVariable(_decl), ""); solAssert(knownVariable(_decl), "");
m_variables.at(&_decl).setZeroValue(); m_variables.at(&_decl).setZeroValue();
} }
void SMTChecker::setUnknownValue(Declaration const& _decl) void SMTChecker::setUnknownValue(VariableDeclaration const& _decl)
{ {
solAssert(knownVariable(_decl), ""); solAssert(knownVariable(_decl), "");
m_variables.at(&_decl).setUnknownValue(); m_variables.at(&_decl).setUnknownValue();
@ -898,8 +898,7 @@ void SMTChecker::removeLocalVariables()
{ {
for (auto it = m_variables.begin(); it != m_variables.end(); ) for (auto it = m_variables.begin(); it != m_variables.end(); )
{ {
VariableDeclaration const& _decl = dynamic_cast<VariableDeclaration const&>(*it->first); if (it->first->isLocalVariable())
if (_decl.isLocalVariable())
it = m_variables.erase(it); it = m_variables.erase(it);
else else
++it; ++it;

View File

@ -76,11 +76,11 @@ private:
/// of rounding for signed division. /// of rounding for signed division.
smt::Expression division(smt::Expression _left, smt::Expression _right, IntegerType const& _type); smt::Expression division(smt::Expression _left, smt::Expression _right, IntegerType const& _type);
void assignment(Declaration const& _variable, Expression const& _value, SourceLocation const& _location); void assignment(VariableDeclaration const& _variable, Expression const& _value, SourceLocation const& _location);
void assignment(Declaration const& _variable, smt::Expression const& _value, SourceLocation const& _location); void assignment(VariableDeclaration const& _variable, smt::Expression const& _value, SourceLocation const& _location);
/// Maps a variable to an SSA index. /// Maps a variable to an SSA index.
using VariableSequenceCounters = std::map<Declaration const*, SSAVariable>; using VariableSequenceCounters = std::map<VariableDeclaration const*, SSAVariable>;
/// Visits the branch given by the statement, pushes and pops the current path conditions. /// Visits the branch given by the statement, pushes and pops the current path conditions.
/// @param _condition if present, asserts that this condition is true within the branch. /// @param _condition if present, asserts that this condition is true within the branch.
@ -114,11 +114,11 @@ private:
void initializeLocalVariables(FunctionDefinition const& _function); void initializeLocalVariables(FunctionDefinition const& _function);
void resetStateVariables(); void resetStateVariables();
void resetVariables(std::vector<Declaration const*> _variables); void resetVariables(std::vector<VariableDeclaration const*> _variables);
/// Given two different branches and the touched variables, /// Given two different branches and the touched variables,
/// merge the touched variables into after-branch ite variables /// merge the touched variables into after-branch ite variables
/// using the branch condition as guard. /// using the branch condition as guard.
void mergeVariables(std::vector<Declaration const*> const& _variables, smt::Expression const& _condition, VariableSequenceCounters const& _countersEndTrue, VariableSequenceCounters const& _countersEndFalse); void mergeVariables(std::vector<VariableDeclaration const*> const& _variables, smt::Expression const& _condition, VariableSequenceCounters const& _countersEndTrue, VariableSequenceCounters const& _countersEndFalse);
/// Tries to create an uninitialized variable and returns true on success. /// Tries to create an uninitialized variable and returns true on success.
/// This fails if the type is not supported. /// This fails if the type is not supported.
bool createVariable(VariableDeclaration const& _varDecl); bool createVariable(VariableDeclaration const& _varDecl);
@ -127,21 +127,21 @@ private:
/// @returns true if _delc is a variable that is known at the current point, i.e. /// @returns true if _delc is a variable that is known at the current point, i.e.
/// has a valid sequence number /// has a valid sequence number
bool knownVariable(Declaration const& _decl); bool knownVariable(VariableDeclaration const& _decl);
/// @returns an expression denoting the value of the variable declared in @a _decl /// @returns an expression denoting the value of the variable declared in @a _decl
/// at the current point. /// at the current point.
smt::Expression currentValue(Declaration const& _decl); smt::Expression currentValue(VariableDeclaration const& _decl);
/// @returns an expression denoting the value of the variable declared in @a _decl /// @returns an expression denoting the value of the variable declared in @a _decl
/// at the given sequence point. Does not ensure that this sequence point exists. /// at the given sequence point. Does not ensure that this sequence point exists.
smt::Expression valueAtSequence(Declaration const& _decl, int _sequence); smt::Expression valueAtSequence(VariableDeclaration const& _decl, int _sequence);
/// Allocates a new sequence number for the declaration, updates the current /// Allocates a new sequence number for the declaration, updates the current
/// sequence number to this value and returns the expression. /// sequence number to this value and returns the expression.
smt::Expression newValue(Declaration const& _decl); smt::Expression newValue(VariableDeclaration const& _decl);
/// Sets the value of the declaration to zero. /// Sets the value of the declaration to zero.
void setZeroValue(Declaration const& _decl); void setZeroValue(VariableDeclaration const& _decl);
/// Resets the variable to an unknown value (in its range). /// Resets the variable to an unknown value (in its range).
void setUnknownValue(Declaration const& decl); void setUnknownValue(VariableDeclaration const& decl);
/// Returns the expression corresponding to the AST node. Throws if the expression does not exist. /// Returns the expression corresponding to the AST node. Throws if the expression does not exist.
smt::Expression expr(Expression const& _e); smt::Expression expr(Expression const& _e);
@ -168,7 +168,7 @@ private:
std::shared_ptr<VariableUsage> m_variableUsage; std::shared_ptr<VariableUsage> m_variableUsage;
bool m_loopExecutionHappened = false; bool m_loopExecutionHappened = false;
std::map<Expression const*, smt::Expression> m_expressions; std::map<Expression const*, smt::Expression> m_expressions;
std::map<Declaration const*, SSAVariable> m_variables; std::map<VariableDeclaration const*, SSAVariable> m_variables;
std::vector<smt::Expression> m_pathConditions; std::vector<smt::Expression> m_pathConditions;
ErrorReporter& m_errorReporter; ErrorReporter& m_errorReporter;

View File

@ -50,12 +50,12 @@ VariableUsage::VariableUsage(ASTNode const& _node)
_node.accept(reducer); _node.accept(reducer);
} }
vector<Declaration const*> VariableUsage::touchedVariables(ASTNode const& _node) const vector<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node) const
{ {
if (!m_children.count(&_node) && !m_touchedVariable.count(&_node)) if (!m_children.count(&_node) && !m_touchedVariable.count(&_node))
return {}; return {};
set<Declaration const*> touched; set<VariableDeclaration const*> touched;
vector<ASTNode const*> toVisit; vector<ASTNode const*> toVisit;
toVisit.push_back(&_node); toVisit.push_back(&_node);

View File

@ -27,7 +27,7 @@ namespace solidity
{ {
class ASTNode; class ASTNode;
class Declaration; class VariableDeclaration;
/** /**
* This class collects information about which local variables of value type * This class collects information about which local variables of value type
@ -38,11 +38,11 @@ class VariableUsage
public: public:
explicit VariableUsage(ASTNode const& _node); explicit VariableUsage(ASTNode const& _node);
std::vector<Declaration const*> touchedVariables(ASTNode const& _node) const; std::vector<VariableDeclaration const*> touchedVariables(ASTNode const& _node) const;
private: private:
// Variable touched by a specific AST node. // Variable touched by a specific AST node.
std::map<ASTNode const*, Declaration const*> m_touchedVariable; std::map<ASTNode const*, VariableDeclaration const*> m_touchedVariable;
std::map<ASTNode const*, std::vector<ASTNode const*>> m_children; std::map<ASTNode const*, std::vector<ASTNode const*>> m_children;
}; };