aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/formal/SMTChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/formal/SMTChecker.cpp')
-rw-r--r--libsolidity/formal/SMTChecker.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp
index db0cec7f..03ec7fac 100644
--- a/libsolidity/formal/SMTChecker.cpp
+++ b/libsolidity/formal/SMTChecker.cpp
@@ -399,16 +399,21 @@ void SMTChecker::visitRequire(FunctionCall const& _funCall)
void SMTChecker::visitGasLeft(FunctionCall const& _funCall)
{
- string gasLeft = "gasleft";
+ string gasLeft = "gasleft()";
// We increase the variable index since gasleft changes
// inside a tx.
defineSpecialVariable(gasLeft, _funCall, true);
- m_specialVariables.at(gasLeft)->setUnknownValue();
+ auto const& symbolicVar = m_specialVariables.at(gasLeft);
+ unsigned index = symbolicVar->index();
+ // We set the current value to unknown anyway to add type constraints.
+ symbolicVar->setUnknownValue();
+ if (index > 0)
+ m_interface->addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1));
}
void SMTChecker::visitBlockHash(FunctionCall const& _funCall)
{
- string blockHash = "blockhash";
+ string blockHash = "blockhash()";
// TODO Define blockhash as an uninterpreted function
defineSpecialVariable(blockHash, _funCall);
}
@@ -480,11 +485,12 @@ void SMTChecker::endVisit(Identifier const& _identifier)
}
else if (FunctionType const* fun = dynamic_cast<FunctionType const*>(_identifier.annotation().type.get()))
{
- if (fun->kind() == FunctionType::Kind::Assert ||
+ if (
+ fun->kind() == FunctionType::Kind::Assert ||
fun->kind() == FunctionType::Kind::Require ||
fun->kind() == FunctionType::Kind::GasLeft ||
fun->kind() == FunctionType::Kind::BlockHash
- )
+ )
return;
createExpr(_identifier);
}
@@ -541,7 +547,16 @@ bool SMTChecker::visit(MemberAccess const& _memberAccess)
solAssert(exprType, "");
if (exprType->category() == Type::Category::Magic)
{
- defineSpecialVariable(_memberAccess.memberName(), _memberAccess);
+ auto identifier = dynamic_cast<Identifier const*>(&_memberAccess.expression());
+ string accessedName;
+ if (identifier)
+ accessedName = identifier->name();
+ else
+ m_errorReporter.warning(
+ _memberAccess.location(),
+ "Assertion checker does not yet support this expression."
+ );
+ defineSpecialVariable(accessedName + "." + _memberAccess.memberName(), _memberAccess);
return false;
}
else