aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Alt <leo@ethereum.org>2018-10-23 00:19:11 +0800
committerLeonardo Alt <leo@ethereum.org>2018-10-23 00:19:11 +0800
commite2cf5f6ed94c571c7478b9a313f8e4fceee2aec3 (patch)
tree02beb0ee9b2db95e1e096ce7d3e7b41e94768f61
parentb46b827c30584968c6815b456b8c0c775c35ae48 (diff)
downloaddexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar.gz
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar.bz2
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar.lz
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar.xz
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.tar.zst
dexon-solidity-e2cf5f6ed94c571c7478b9a313f8e4fceee2aec3.zip
Add gasleft constraint and use full member access name
-rw-r--r--libsolidity/formal/SMTChecker.cpp27
-rw-r--r--libsolidity/formal/SSAVariable.cpp2
-rw-r--r--libsolidity/formal/SSAVariable.h10
-rw-r--r--libsolidity/formal/SymbolicVariable.cpp2
-rw-r--r--libsolidity/formal/SymbolicVariable.h6
-rw-r--r--test/libsolidity/smtCheckerTests/special/difficulty.sol10
-rw-r--r--test/libsolidity/smtCheckerTests/special/gasleft.sol4
7 files changed, 45 insertions, 16 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
diff --git a/libsolidity/formal/SSAVariable.cpp b/libsolidity/formal/SSAVariable.cpp
index dbc58664..36e15508 100644
--- a/libsolidity/formal/SSAVariable.cpp
+++ b/libsolidity/formal/SSAVariable.cpp
@@ -28,6 +28,6 @@ SSAVariable::SSAVariable()
void SSAVariable::resetIndex()
{
m_currentIndex = 0;
- m_nextFreeIndex.reset (new int);
+ m_nextFreeIndex.reset (new unsigned);
*m_nextFreeIndex = 1;
}
diff --git a/libsolidity/formal/SSAVariable.h b/libsolidity/formal/SSAVariable.h
index d357740d..46935472 100644
--- a/libsolidity/formal/SSAVariable.h
+++ b/libsolidity/formal/SSAVariable.h
@@ -34,19 +34,19 @@ public:
void resetIndex();
/// This function returns the current index of this SSA variable.
- int index() const { return m_currentIndex; }
- int& index() { return m_currentIndex; }
+ unsigned index() const { return m_currentIndex; }
+ unsigned& index() { return m_currentIndex; }
- int operator++()
+ unsigned operator++()
{
return m_currentIndex = (*m_nextFreeIndex)++;
}
private:
- int m_currentIndex;
+ unsigned m_currentIndex;
/// The next free index is a shared pointer because we want
/// the copy and the copied to share it.
- std::shared_ptr<int> m_nextFreeIndex;
+ std::shared_ptr<unsigned> m_nextFreeIndex;
};
}
diff --git a/libsolidity/formal/SymbolicVariable.cpp b/libsolidity/formal/SymbolicVariable.cpp
index 8259ffee..530564d2 100644
--- a/libsolidity/formal/SymbolicVariable.cpp
+++ b/libsolidity/formal/SymbolicVariable.cpp
@@ -35,7 +35,7 @@ SymbolicVariable::SymbolicVariable(
{
}
-string SymbolicVariable::uniqueSymbol(int _index) const
+string SymbolicVariable::uniqueSymbol(unsigned _index) const
{
return m_uniqueName + "_" + to_string(_index);
}
diff --git a/libsolidity/formal/SymbolicVariable.h b/libsolidity/formal/SymbolicVariable.h
index 9beaf0e0..e554139f 100644
--- a/libsolidity/formal/SymbolicVariable.h
+++ b/libsolidity/formal/SymbolicVariable.h
@@ -59,8 +59,8 @@ public:
return currentValue();
}
- int index() const { return m_ssa->index(); }
- int& index() { return m_ssa->index(); }
+ unsigned index() const { return m_ssa->index(); }
+ unsigned& index() { return m_ssa->index(); }
/// Sets the var to the default value of its type.
/// Inherited types must implement.
@@ -70,7 +70,7 @@ public:
virtual void setUnknownValue() {}
protected:
- std::string uniqueSymbol(int _index) const;
+ std::string uniqueSymbol(unsigned _index) const;
TypePointer m_type = nullptr;
std::string m_uniqueName;
diff --git a/test/libsolidity/smtCheckerTests/special/difficulty.sol b/test/libsolidity/smtCheckerTests/special/difficulty.sol
new file mode 100644
index 00000000..4469d4e5
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/special/difficulty.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+
+contract C
+{
+ function f(uint difficulty) public view {
+ assert(block.difficulty == difficulty);
+ }
+}
+// ----
+// Warning: (91-129): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/special/gasleft.sol b/test/libsolidity/smtCheckerTests/special/gasleft.sol
index ec56d957..857230fe 100644
--- a/test/libsolidity/smtCheckerTests/special/gasleft.sol
+++ b/test/libsolidity/smtCheckerTests/special/gasleft.sol
@@ -4,7 +4,11 @@ contract C
{
function f() public view {
assert(gasleft() > 0);
+ uint g = gasleft();
+ assert(g < gasleft());
+ assert(g >= gasleft());
}
}
// ----
// Warning: (76-97): Assertion violation happens here
+// Warning: (123-144): Assertion violation happens here