Merge pull request #9670 from ethereum/smt_struct

[SMTChecker] Support structs
This commit is contained in:
Leonardo 2020-09-03 17:50:56 +02:00 committed by GitHub
commit f964966090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 1331 additions and 414 deletions

View File

@ -4,6 +4,7 @@ Language Features:
Compiler Features:
* SMTChecker: Support structs.
* Yul Optimizer: Prune unused parameters in functions.
Bugfixes:

View File

@ -580,7 +580,7 @@ pair<vector<smtutil::Expression>, vector<string>> BMC::modelExpressions()
auto const& type = var.second->type();
if (
type->isValueType() &&
smt::smtKind(type->category()) != smtutil::Kind::Function
smt::smtKind(*type) != smtutil::Kind::Function
)
{
expressionsToEvaluate.emplace_back(var.second->currentValue());

View File

@ -378,7 +378,7 @@ void SMTEncoder::endVisit(Assignment const& _assignment)
"Assertion checker does not yet implement this assignment operator."
);
}
else if (!smt::isSupportedType(_assignment.annotation().type->category()))
else if (!smt::isSupportedType(*_assignment.annotation().type))
{
// Give it a new index anyway to keep the SSA scheme sound.
@ -403,8 +403,7 @@ void SMTEncoder::endVisit(Assignment const& _assignment)
assignment(
_assignment.leftHandSide(),
expr(_assignment, type),
type,
_assignment.location()
type
);
}
}
@ -463,20 +462,19 @@ void SMTEncoder::endVisit(UnaryOperation const& _op)
createExpr(_op);
auto const* subExpr = innermostTuple(_op.subExpression());
auto type = _op.annotation().type;
switch (_op.getOperator())
{
case Token::Not: // !
{
solAssert(smt::isBool(_op.annotation().type->category()), "");
solAssert(smt::isBool(*type), "");
defineExpr(_op, !expr(*subExpr));
break;
}
case Token::Inc: // ++ (pre- or postfix)
case Token::Dec: // -- (pre- or postfix)
{
auto cat = _op.annotation().type->category();
solAssert(smt::isInteger(cat) || smt::isFixedPoint(cat), "");
solAssert(smt::isInteger(*type) || smt::isFixedPoint(*type), "");
solAssert(subExpr->annotation().willBeWrittenTo, "");
if (auto identifier = dynamic_cast<Identifier const*>(subExpr))
{
@ -487,12 +485,15 @@ void SMTEncoder::endVisit(UnaryOperation const& _op)
defineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue);
assignment(*decl, newValue);
}
else if (dynamic_cast<IndexAccess const*>(subExpr))
else if (
dynamic_cast<IndexAccess const*>(&_op.subExpression()) ||
dynamic_cast<MemberAccess const*>(&_op.subExpression())
)
{
auto innerValue = expr(*subExpr);
auto newValue = _op.getOperator() == Token::Inc ? innerValue + 1 : innerValue - 1;
defineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue);
arrayIndexAssignment(*subExpr, newValue);
indexOrMemberAssignment(_op.subExpression(), newValue);
}
else
m_errorReporter.warning(
@ -521,14 +522,13 @@ void SMTEncoder::endVisit(UnaryOperation const& _op)
auto const& symbVar = m_context.expression(*subExpr);
symbVar->increaseIndex();
m_context.setZeroValue(*symbVar);
if (dynamic_cast<IndexAccess const*>(subExpr))
arrayIndexAssignment(*subExpr, symbVar->currentValue());
if (
dynamic_cast<IndexAccess const*>(&_op.subExpression()) ||
dynamic_cast<MemberAccess const*>(&_op.subExpression())
)
indexOrMemberAssignment(_op.subExpression(), symbVar->currentValue());
else
m_errorReporter.warning(
2683_error,
_op.location(),
"Assertion checker does not yet implement \"delete\" for this expression."
);
solAssert(false, "");
}
break;
}
@ -826,11 +826,11 @@ void SMTEncoder::endVisit(Literal const& _literal)
{
solAssert(_literal.annotation().type, "Expected type for AST node");
Type const& type = *_literal.annotation().type;
if (smt::isNumber(type.category()))
if (smt::isNumber(type))
defineExpr(_literal, smtutil::Expression(type.literalValue(&_literal)));
else if (smt::isBool(type.category()))
else if (smt::isBool(type))
defineExpr(_literal, smtutil::Expression(_literal.token() == Token::TrueLiteral ? true : false));
else if (smt::isStringLiteral(type.category()))
else if (smt::isStringLiteral(type))
createExpr(_literal);
else
{
@ -893,6 +893,13 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
defineGlobalVariable(accessedName + "." + _memberAccess.memberName(), _memberAccess);
return false;
}
else if (smt::isNonRecursiveStruct(*exprType))
{
_memberAccess.expression().accept(*this);
auto const& symbStruct = dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(_memberAccess.expression()));
defineExpr(_memberAccess, symbStruct->member(_memberAccess.memberName()));
return false;
}
else if (exprType->category() == Type::Category::TypeType)
{
if (identifier && dynamic_cast<EnumDefinition const*>(identifier->annotation().referencedDeclaration))
@ -964,19 +971,10 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
solAssert(varDecl, "");
array = m_context.variable(*varDecl);
}
else if (auto const* innerAccess = dynamic_cast<IndexAccess const*>(&_indexAccess.baseExpression()))
{
solAssert(m_context.knownExpression(*innerAccess), "");
array = m_context.expression(*innerAccess);
}
else
{
m_errorReporter.warning(
9118_error,
_indexAccess.location(),
"Assertion checker does not yet implement this expression."
);
return;
solAssert(m_context.knownExpression(_indexAccess.baseExpression()), "");
array = m_context.expression(_indexAccess.baseExpression());
}
auto arrayVar = dynamic_pointer_cast<smt::SymbolicArrayVariable>(array);
@ -1008,14 +1006,58 @@ void SMTEncoder::arrayAssignment()
m_arrayAssignmentHappened = true;
}
void SMTEncoder::arrayIndexAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide)
void SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide)
{
auto toStore = _rightHandSide;
auto indexAccess = dynamic_cast<IndexAccess const*>(&_expr);
solAssert(indexAccess, "");
auto const* lastExpr = &_expr;
while (true)
{
if (auto const& id = dynamic_cast<Identifier const*>(&indexAccess->baseExpression()))
if (auto const* indexAccess = dynamic_cast<IndexAccess const*>(lastExpr))
{
auto const& base = indexAccess->baseExpression();
if (dynamic_cast<Identifier const*>(&base))
base.accept(*this);
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(base));
solAssert(symbArray, "");
auto baseType = symbArray->type();
toStore = smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)),
{smtutil::Expression::store(symbArray->elements(), expr(*indexAccess->indexExpression()), toStore), symbArray->length()}
);
m_context.expression(*indexAccess)->increaseIndex();
defineExpr(*indexAccess, smtutil::Expression::select(
symbArray->elements(),
expr(*indexAccess->indexExpression())
));
lastExpr = &indexAccess->baseExpression();
}
else if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(lastExpr))
{
auto const& base = memberAccess->expression();
if (dynamic_cast<Identifier const*>(&base))
base.accept(*this);
if (
auto const* structType = dynamic_cast<StructType const*>(base.annotation().type);
structType && structType->recursive()
)
{
m_errorReporter.warning(
4375_error,
memberAccess->location(),
"Assertion checker does not support recursive structs."
);
return;
}
auto symbStruct = dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(base));
solAssert(symbStruct, "");
symbStruct->assignMember(memberAccess->memberName(), toStore);
toStore = symbStruct->currentValue();
defineExpr(*memberAccess, symbStruct->member(memberAccess->memberName()));
lastExpr = &memberAccess->expression();
}
else if (auto const& id = dynamic_cast<Identifier const*>(lastExpr))
{
auto varDecl = identifierToVariable(*id);
solAssert(varDecl, "");
@ -1023,43 +1065,22 @@ void SMTEncoder::arrayIndexAssignment(Expression const& _expr, smtutil::Expressi
if (varDecl->hasReferenceOrMappingType())
resetReferences(*varDecl);
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.variable(*varDecl));
smtutil::Expression store = smtutil::Expression::store(
symbArray->elements(),
expr(*indexAccess->indexExpression()),
toStore
);
auto oldLength = symbArray->length();
symbArray->increaseIndex();
m_context.addAssertion(symbArray->elements() == store);
m_context.addAssertion(symbArray->length() == oldLength);
// Update the SMT select value after the assignment,
// necessary for sound models.
defineExpr(*indexAccess, smtutil::Expression::select(
symbArray->elements(),
expr(*indexAccess->indexExpression())
));
m_context.addAssertion(m_context.newValue(*varDecl) == toStore);
m_context.expression(*id)->increaseIndex();
defineExpr(*id,currentValue(*varDecl));
break;
}
else if (auto base = dynamic_cast<IndexAccess const*>(&indexAccess->baseExpression()))
{
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*base));
solAssert(symbArray, "");
auto baseType = base->annotation().type;
toStore = smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)),
{smtutil::Expression::store(symbArray->elements(), expr(*indexAccess->indexExpression()), toStore), symbArray->length()}
);
indexAccess = base;
}
else
{
m_errorReporter.warning(
9056_error,
_expr.location(),
"Assertion checker does not yet implement this expression."
);
auto type = lastExpr->annotation().type;
if (
dynamic_cast<ReferenceType const*>(type) ||
dynamic_cast<MappingType const*>(type)
)
resetReferences(type);
m_context.expression(*lastExpr)->increaseIndex();
m_context.addAssertion(expr(*lastExpr) == toStore);
break;
}
}
@ -1131,9 +1152,14 @@ void SMTEncoder::arrayPushPopAssign(Expression const& _expr, smtutil::Expression
if (varDecl->hasReferenceOrMappingType())
resetReferences(*varDecl);
m_context.addAssertion(m_context.newValue(*varDecl) == _array);
m_context.expression(*id)->increaseIndex();
defineExpr(*id,currentValue(*varDecl));
}
else if (auto const* indexAccess = dynamic_cast<IndexAccess const*>(expr))
arrayIndexAssignment(*indexAccess, _array);
else if (
dynamic_cast<IndexAccess const*>(expr) ||
dynamic_cast<MemberAccess const*>(expr)
)
indexOrMemberAssignment(_expr, _array);
else if (auto const* funCall = dynamic_cast<FunctionCall const*>(expr))
{
FunctionType const& funType = dynamic_cast<FunctionType const&>(*funCall->expression().annotation().type);
@ -1156,12 +1182,6 @@ void SMTEncoder::arrayPushPopAssign(Expression const& _expr, smtutil::Expression
arrayPushPopAssign(memberAccess->expression(), symbArray->currentValue());
}
}
else if (dynamic_cast<MemberAccess const*>(expr))
m_errorReporter.warning(
9599_error,
_expr.location(),
"Assertion checker does not yet implement this expression."
);
else
solAssert(false, "");
}
@ -1182,7 +1202,7 @@ void SMTEncoder::defineGlobalVariable(string const& _name, Expression const& _ex
m_context.globalSymbol(_name)->increaseIndex();
// The default behavior is not to increase the index since
// most of the global values stay the same throughout a tx.
if (smt::isSupportedType(_expr.annotation().type->category()))
if (smt::isSupportedType(*_expr.annotation().type))
defineExpr(_expr, m_context.globalSymbol(_name)->currentValue());
}
@ -1335,13 +1355,13 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
{
auto const& commonType = _op.annotation().commonType;
solAssert(commonType, "");
if (smt::isSupportedType(commonType->category()))
if (smt::isSupportedType(*commonType))
{
smtutil::Expression left(expr(_op.leftExpression(), commonType));
smtutil::Expression right(expr(_op.rightExpression(), commonType));
Token op = _op.getOperator();
shared_ptr<smtutil::Expression> value;
if (smt::isNumber(commonType->category()))
if (smt::isNumber(*commonType))
{
value = make_shared<smtutil::Expression>(
op == Token::Equal ? (left == right) :
@ -1354,7 +1374,7 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
}
else // Bool
{
solUnimplementedAssert(smt::isBool(commonType->category()), "Operation not yet supported");
solUnimplementedAssert(smt::isBool(*commonType), "Operation not yet supported");
value = make_shared<smtutil::Expression>(
op == Token::Equal ? (left == right) :
/*op == Token::NotEqual*/ (left != right)
@ -1450,8 +1470,7 @@ smtutil::Expression SMTEncoder::division(smtutil::Expression _left, smtutil::Exp
void SMTEncoder::assignment(
Expression const& _left,
smtutil::Expression const& _right,
TypePointer const& _type,
langutil::SourceLocation const& _location
TypePointer const& _type
)
{
solAssert(
@ -1461,28 +1480,21 @@ void SMTEncoder::assignment(
Expression const* left = innermostTuple(_left);
if (!smt::isSupportedType(_type->category()))
if (!smt::isSupportedType(*_type))
{
// Give it a new index anyway to keep the SSA scheme sound.
if (auto varDecl = identifierToVariable(*left))
m_context.newValue(*varDecl);
m_errorReporter.warning(
6191_error,
_location,
"Assertion checker does not yet implement type " + _type->toString()
);
}
else if (auto varDecl = identifierToVariable(*left))
assignment(*varDecl, _right);
else if (dynamic_cast<IndexAccess const*>(left))
arrayIndexAssignment(*left, _right);
else if (
dynamic_cast<IndexAccess const*>(left) ||
dynamic_cast<MemberAccess const*>(left)
)
indexOrMemberAssignment(*left, _right);
else
m_errorReporter.warning(
8182_error,
_location,
"Assertion checker does not yet implement such assignments."
);
solAssert(false, "");
}
void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _right)
@ -1511,7 +1523,7 @@ void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _rig
else
{
auto type = lExpr.annotation().type;
assignment(lExpr, expr(rExpr, type), type, lExpr.location());
assignment(lExpr, expr(rExpr, type), type);
}
}
}
@ -1528,7 +1540,7 @@ void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _rig
for (unsigned i = 0; i < lComponents.size(); ++i)
if (auto component = lComponents.at(i); component && rComponents.at(i))
assignment(*component, smtutil::Expression::tuple_get(symbRight, i), component->annotation().type, component->location());
assignment(*component, smtutil::Expression::tuple_get(symbRight, i), component->annotation().type);
}
}
@ -1692,32 +1704,43 @@ void SMTEncoder::resetReferences(VariableDeclaration const& _varDecl)
if (_var.isStateVariable() && _varDecl.isStateVariable())
return false;
TypePointer prefix = _var.type();
TypePointer originalType = typeWithoutPointer(_varDecl.type());
while (
prefix->category() == Type::Category::Mapping ||
prefix->category() == Type::Category::Array
)
{
if (*originalType == *typeWithoutPointer(prefix))
return true;
if (prefix->category() == Type::Category::Mapping)
{
auto mapPrefix = dynamic_cast<MappingType const*>(prefix);
solAssert(mapPrefix, "");
prefix = mapPrefix->valueType();
}
else
{
auto arrayPrefix = dynamic_cast<ArrayType const*>(prefix);
solAssert(arrayPrefix, "");
prefix = arrayPrefix->baseType();
}
}
return false;
return sameTypeOrSubtype(_var.type(), _varDecl.type());
});
}
void SMTEncoder::resetReferences(TypePointer _type)
{
m_context.resetVariables([&](VariableDeclaration const& _var) {
return sameTypeOrSubtype(_var.type(), _type);
});
}
bool SMTEncoder::sameTypeOrSubtype(TypePointer _a, TypePointer _b)
{
TypePointer prefix = _a;
while (
prefix->category() == Type::Category::Mapping ||
prefix->category() == Type::Category::Array
)
{
if (*typeWithoutPointer(_b) == *typeWithoutPointer(prefix))
return true;
if (prefix->category() == Type::Category::Mapping)
{
auto mapPrefix = dynamic_cast<MappingType const*>(prefix);
solAssert(mapPrefix, "");
prefix = mapPrefix->valueType();
}
else
{
auto arrayPrefix = dynamic_cast<ArrayType const*>(prefix);
solAssert(arrayPrefix, "");
prefix = arrayPrefix->baseType();
}
}
return false;
}
TypePointer SMTEncoder::typeWithoutPointer(TypePointer const& _type)
{
if (auto refType = dynamic_cast<ReferenceType const*>(_type))

View File

@ -146,8 +146,8 @@ protected:
/// to variable of some SMT array type
/// while aliasing is not supported.
void arrayAssignment();
/// Handles assignment to SMT array index.
void arrayIndexAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide);
/// Handles assignments to index or member access.
void indexOrMemberAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide);
void arrayPush(FunctionCall const& _funCall);
void arrayPop(FunctionCall const& _funCall);
@ -168,8 +168,7 @@ protected:
void assignment(
Expression const& _left,
smtutil::Expression const& _right,
TypePointer const& _type,
langutil::SourceLocation const& _location
TypePointer const& _type
);
/// Handle assignments between tuples.
void tupleAssignment(Expression const& _left, Expression const& _right);
@ -196,8 +195,12 @@ protected:
/// Resets all references/pointers that have the same type or have
/// a subexpression of the same type as _varDecl.
void resetReferences(VariableDeclaration const& _varDecl);
/// Resets all references/pointers that have type _type.
void resetReferences(TypePointer _type);
/// @returns the type without storage pointer information if it has it.
TypePointer typeWithoutPointer(TypePointer const& _type);
/// @returns whether _a or a subtype of _a is the same as _b.
bool sameTypeOrSubtype(TypePointer _a, TypePointer _b);
/// Given two different branches and the touched variables,
/// merge the touched variables into after-branch ite variables

View File

@ -25,6 +25,7 @@
#include <vector>
using namespace std;
using namespace solidity::util;
using namespace solidity::smtutil;
namespace solidity::frontend::smt
@ -32,7 +33,7 @@ namespace solidity::frontend::smt
SortPointer smtSort(frontend::Type const& _type)
{
switch (smtKind(_type.category()))
switch (smtKind(_type))
{
case Kind::Int:
if (auto const* intType = dynamic_cast<IntegerType const*>(&_type))
@ -63,13 +64,13 @@ SortPointer smtSort(frontend::Type const& _type)
case Kind::Array:
{
shared_ptr<ArraySort> array;
if (isMapping(_type.category()))
if (isMapping(_type))
{
auto mapType = dynamic_cast<frontend::MappingType const*>(&_type);
solAssert(mapType, "");
array = make_shared<ArraySort>(smtSortAbstractFunction(*mapType->keyType()), smtSortAbstractFunction(*mapType->valueType()));
}
else if (isStringLiteral(_type.category()))
else if (isStringLiteral(_type))
{
auto stringLitType = dynamic_cast<frontend::StringLiteralType const*>(&_type);
solAssert(stringLitType, "");
@ -130,18 +131,32 @@ SortPointer smtSort(frontend::Type const& _type)
}
case Kind::Tuple:
{
auto tupleType = dynamic_cast<frontend::TupleType const*>(&_type);
solAssert(tupleType, "");
vector<string> members;
auto const& tupleName = _type.identifier();
auto const& components = tupleType->components();
for (unsigned i = 0; i < components.size(); ++i)
members.emplace_back(tupleName + "_accessor_" + to_string(i));
return make_shared<TupleSort>(
tupleName,
members,
smtSortAbstractFunction(tupleType->components())
);
auto const& tupleName = _type.toString(true);
vector<SortPointer> sorts;
if (auto const* tupleType = dynamic_cast<frontend::TupleType const*>(&_type))
{
auto const& components = tupleType->components();
for (unsigned i = 0; i < components.size(); ++i)
members.emplace_back(tupleName + "_accessor_" + to_string(i));
sorts = smtSortAbstractFunction(tupleType->components());
}
else if (auto const* structType = dynamic_cast<frontend::StructType const*>(&_type))
{
solAssert(!structType->recursive(), "");
auto const& structMembers = structType->structDefinition().members();
for (auto member: structMembers)
members.emplace_back(tupleName + "_accessor_" + member->name());
sorts = smtSortAbstractFunction(applyMap(
structMembers,
[](auto var) { return var->type(); }
));
}
else
solAssert(false, "");
return make_shared<TupleSort>(tupleName, members, sorts);
}
default:
// Abstract case.
@ -159,7 +174,7 @@ vector<SortPointer> smtSort(vector<frontend::TypePointer> const& _types)
SortPointer smtSortAbstractFunction(frontend::Type const& _type)
{
if (isFunction(_type.category()))
if (isFunction(_type))
return SortProvider::uintSort;
return smtSort(_type);
}
@ -175,35 +190,36 @@ vector<SortPointer> smtSortAbstractFunction(vector<frontend::TypePointer> const&
return sorts;
}
Kind smtKind(frontend::Type::Category _category)
Kind smtKind(frontend::Type const& _type)
{
if (isNumber(_category))
if (isNumber(_type))
return Kind::Int;
else if (isBool(_category))
else if (isBool(_type))
return Kind::Bool;
else if (isFunction(_category))
else if (isFunction(_type))
return Kind::Function;
else if (isMapping(_category) || isArray(_category))
else if (isMapping(_type) || isArray(_type))
return Kind::Array;
else if (isTuple(_category))
else if (isTuple(_type) || isNonRecursiveStruct(_type))
return Kind::Tuple;
// Abstract case.
return Kind::Int;
}
bool isSupportedType(frontend::Type::Category _category)
bool isSupportedType(frontend::Type const& _type)
{
return isNumber(_category) ||
isBool(_category) ||
isMapping(_category) ||
isArray(_category) ||
isTuple(_category);
return isNumber(_type) ||
isBool(_type) ||
isMapping(_type) ||
isArray(_type) ||
isTuple(_type) ||
isNonRecursiveStruct(_type);
}
bool isSupportedTypeDeclaration(frontend::Type::Category _category)
bool isSupportedTypeDeclaration(frontend::Type const& _type)
{
return isSupportedType(_category) ||
isFunction(_category);
return isSupportedType(_type) ||
isFunction(_type);
}
pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
@ -220,9 +236,9 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
abstract = true;
var = make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);
}
else if (isBool(_type.category()))
else if (isBool(_type))
var = make_shared<SymbolicBoolVariable>(type, _uniqueName, _context);
else if (isFunction(_type.category()))
else if (isFunction(_type))
{
auto const& fType = dynamic_cast<FunctionType const*>(type);
auto const& paramsIn = fType->parameterTypes();
@ -245,21 +261,21 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
else
var = make_shared<SymbolicFunctionVariable>(type, _uniqueName, _context);
}
else if (isInteger(_type.category()))
else if (isInteger(_type))
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
else if (isFixedPoint(_type.category()))
else if (isFixedPoint(_type))
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
else if (isFixedBytes(_type.category()))
else if (isFixedBytes(_type))
{
auto fixedBytesType = dynamic_cast<frontend::FixedBytesType const*>(type);
solAssert(fixedBytesType, "");
var = make_shared<SymbolicFixedBytesVariable>(type, fixedBytesType->numBytes(), _uniqueName, _context);
}
else if (isAddress(_type.category()) || isContract(_type.category()))
else if (isAddress(_type) || isContract(_type))
var = make_shared<SymbolicAddressVariable>(_uniqueName, _context);
else if (isEnum(_type.category()))
else if (isEnum(_type))
var = make_shared<SymbolicEnumVariable>(type, _uniqueName, _context);
else if (isRational(_type.category()))
else if (isRational(_type))
{
auto rational = dynamic_cast<frontend::RationalNumberType const*>(&_type);
solAssert(rational, "");
@ -268,106 +284,104 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
else
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
}
else if (isMapping(_type.category()) || isArray(_type.category()))
else if (isMapping(_type) || isArray(_type))
var = make_shared<SymbolicArrayVariable>(type, type, _uniqueName, _context);
else if (isTuple(_type.category()))
else if (isTuple(_type))
var = make_shared<SymbolicTupleVariable>(type, _uniqueName, _context);
else if (isStringLiteral(_type.category()))
else if (isStringLiteral(_type))
{
auto stringType = TypeProvider::stringMemory();
var = make_shared<SymbolicArrayVariable>(stringType, type, _uniqueName, _context);
}
else if (isNonRecursiveStruct(_type))
var = make_shared<SymbolicStructVariable>(type, _uniqueName, _context);
else
solAssert(false, "");
return make_pair(abstract, var);
}
bool isSupportedType(frontend::Type const& _type)
bool isInteger(frontend::Type const& _type)
{
return isSupportedType(_type.category());
return _type.category() == frontend::Type::Category::Integer;
}
bool isSupportedTypeDeclaration(frontend::Type const& _type)
bool isFixedPoint(frontend::Type const& _type)
{
return isSupportedTypeDeclaration(_type.category());
return _type.category() == frontend::Type::Category::FixedPoint;
}
bool isInteger(frontend::Type::Category _category)
bool isRational(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Integer;
return _type.category() == frontend::Type::Category::RationalNumber;
}
bool isFixedPoint(frontend::Type::Category _category)
bool isFixedBytes(frontend::Type const& _type)
{
return _category == frontend::Type::Category::FixedPoint;
return _type.category() == frontend::Type::Category::FixedBytes;
}
bool isRational(frontend::Type::Category _category)
bool isAddress(frontend::Type const& _type)
{
return _category == frontend::Type::Category::RationalNumber;
return _type.category() == frontend::Type::Category::Address;
}
bool isFixedBytes(frontend::Type::Category _category)
bool isContract(frontend::Type const& _type)
{
return _category == frontend::Type::Category::FixedBytes;
return _type.category() == frontend::Type::Category::Contract;
}
bool isAddress(frontend::Type::Category _category)
bool isEnum(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Address;
return _type.category() == frontend::Type::Category::Enum;
}
bool isContract(frontend::Type::Category _category)
bool isNumber(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Contract;
return isInteger(_type) ||
isFixedPoint(_type) ||
isRational(_type) ||
isFixedBytes(_type) ||
isAddress(_type) ||
isContract(_type) ||
isEnum(_type);
}
bool isEnum(frontend::Type::Category _category)
bool isBool(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Enum;
return _type.category() == frontend::Type::Category::Bool;
}
bool isNumber(frontend::Type::Category _category)
bool isFunction(frontend::Type const& _type)
{
return isInteger(_category) ||
isFixedPoint(_category) ||
isRational(_category) ||
isFixedBytes(_category) ||
isAddress(_category) ||
isContract(_category) ||
isEnum(_category);
return _type.category() == frontend::Type::Category::Function;
}
bool isBool(frontend::Type::Category _category)
bool isMapping(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Bool;
return _type.category() == frontend::Type::Category::Mapping;
}
bool isFunction(frontend::Type::Category _category)
bool isArray(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Function;
return _type.category() == frontend::Type::Category::Array ||
_type.category() == frontend::Type::Category::StringLiteral ||
_type.category() == frontend::Type::Category::ArraySlice;
}
bool isMapping(frontend::Type::Category _category)
bool isTuple(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Mapping;
return _type.category() == frontend::Type::Category::Tuple;
}
bool isArray(frontend::Type::Category _category)
bool isStringLiteral(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Array ||
_category == frontend::Type::Category::StringLiteral ||
_category == frontend::Type::Category::ArraySlice;
return _type.category() == frontend::Type::Category::StringLiteral;
}
bool isTuple(frontend::Type::Category _category)
bool isNonRecursiveStruct(frontend::Type const& _type)
{
return _category == frontend::Type::Category::Tuple;
}
bool isStringLiteral(frontend::Type::Category _category)
{
return _category == frontend::Type::Category::StringLiteral;
auto structType = dynamic_cast<StructType const*>(&_type);
return structType && !structType->recursive();
}
smtutil::Expression minValue(frontend::IntegerType const& _type)
@ -394,13 +408,13 @@ void setSymbolicZeroValue(smtutil::Expression _expr, frontend::TypePointer const
smtutil::Expression zeroValue(frontend::TypePointer const& _type)
{
solAssert(_type, "");
if (isSupportedType(_type->category()))
if (isSupportedType(*_type))
{
if (isNumber(_type->category()))
if (isNumber(*_type))
return 0;
if (isBool(_type->category()))
if (isBool(*_type))
return smtutil::Expression(false);
if (isArray(_type->category()) || isMapping(_type->category()))
if (isArray(*_type) || isMapping(*_type))
{
auto tupleSort = dynamic_pointer_cast<TupleSort>(smtSort(*_type));
solAssert(tupleSort, "");
@ -421,11 +435,23 @@ smtutil::Expression zeroValue(frontend::TypePointer const& _type)
solAssert(zeroArray, "");
return smtutil::Expression::tuple_constructor(
smtutil::Expression(std::make_shared<SortSort>(smtSort(*_type)), _type->toString(true)),
smtutil::Expression(std::make_shared<SortSort>(tupleSort), tupleSort->name),
vector<smtutil::Expression>{*zeroArray, length}
);
}
if (isNonRecursiveStruct(*_type))
{
auto const* structType = dynamic_cast<StructType const*>(_type);
auto structSort = dynamic_pointer_cast<TupleSort>(smtSort(*_type));
return smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<SortSort>(structSort), structSort->name),
applyMap(
structType->structDefinition().members(),
[](auto var) { return zeroValue(var->type()); }
)
);
}
solAssert(false, "");
}
// Unsupported types are abstracted as Int.
@ -452,14 +478,14 @@ void setSymbolicUnknownValue(SymbolicVariable const& _variable, EncodingContext&
void setSymbolicUnknownValue(smtutil::Expression _expr, frontend::TypePointer const& _type, EncodingContext& _context)
{
solAssert(_type, "");
if (isEnum(_type->category()))
if (isEnum(*_type))
{
auto enumType = dynamic_cast<frontend::EnumType const*>(_type);
solAssert(enumType, "");
_context.addAssertion(_expr >= 0);
_context.addAssertion(_expr < enumType->numberOfMembers());
}
else if (isInteger(_type->category()))
else if (isInteger(*_type))
{
auto intType = dynamic_cast<frontend::IntegerType const*>(_type);
solAssert(intType, "");

View File

@ -34,29 +34,30 @@ std::vector<smtutil::SortPointer> smtSort(std::vector<frontend::TypePointer> con
smtutil::SortPointer smtSortAbstractFunction(frontend::Type const& _type);
std::vector<smtutil::SortPointer> smtSortAbstractFunction(std::vector<frontend::TypePointer> const& _types);
/// Returns the SMT kind that models the Solidity type type category _category.
smtutil::Kind smtKind(frontend::Type::Category _category);
smtutil::Kind smtKind(frontend::Type const& _type);
/// Returns true if type is fully supported (declaration and operations).
bool isSupportedType(frontend::Type::Category _category);
bool isSupportedType(frontend::Type const& _type);
bool isSupportedType(frontend::Type const& _type);
/// Returns true if type is partially supported (declaration).
bool isSupportedTypeDeclaration(frontend::Type::Category _category);
bool isSupportedTypeDeclaration(frontend::Type const& _type);
bool isSupportedTypeDeclaration(frontend::Type const& _type);
bool isInteger(frontend::Type::Category _category);
bool isFixedPoint(frontend::Type::Category _category);
bool isRational(frontend::Type::Category _category);
bool isFixedBytes(frontend::Type::Category _category);
bool isAddress(frontend::Type::Category _category);
bool isContract(frontend::Type::Category _category);
bool isEnum(frontend::Type::Category _category);
bool isNumber(frontend::Type::Category _category);
bool isBool(frontend::Type::Category _category);
bool isFunction(frontend::Type::Category _category);
bool isMapping(frontend::Type::Category _category);
bool isArray(frontend::Type::Category _category);
bool isTuple(frontend::Type::Category _category);
bool isStringLiteral(frontend::Type::Category _category);
bool isInteger(frontend::Type const& _type);
bool isFixedPoint(frontend::Type const& _type);
bool isRational(frontend::Type const& _type);
bool isFixedBytes(frontend::Type const& _type);
bool isAddress(frontend::Type const& _type);
bool isContract(frontend::Type const& _type);
bool isEnum(frontend::Type const& _type);
bool isNumber(frontend::Type const& _type);
bool isBool(frontend::Type const& _type);
bool isFunction(frontend::Type const& _type);
bool isMapping(frontend::Type const& _type);
bool isArray(frontend::Type const& _type);
bool isTuple(frontend::Type const& _type);
bool isStringLiteral(frontend::Type const& _type);
bool isNonRecursiveStruct(frontend::Type const& _type);
/// Returns a new symbolic variable, according to _type.
/// Also returns whether the type is abstract or not,

View File

@ -21,8 +21,11 @@
#include <libsolidity/formal/SymbolicTypes.h>
#include <libsolidity/ast/AST.h>
#include <libsolutil/Algorithms.h>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::smtutil;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;
@ -118,7 +121,7 @@ SymbolicIntVariable::SymbolicIntVariable(
):
SymbolicVariable(_type, _originalType, move(_uniqueName), _context)
{
solAssert(isNumber(m_type->category()), "");
solAssert(isNumber(*m_type), "");
}
SymbolicAddressVariable::SymbolicAddressVariable(
@ -218,7 +221,7 @@ SymbolicEnumVariable::SymbolicEnumVariable(
):
SymbolicVariable(_type, _type, move(_uniqueName), _context)
{
solAssert(isEnum(m_type->category()), "");
solAssert(isEnum(*m_type), "");
}
SymbolicTupleVariable::SymbolicTupleVariable(
@ -228,7 +231,7 @@ SymbolicTupleVariable::SymbolicTupleVariable(
):
SymbolicVariable(_type, _type, move(_uniqueName), _context)
{
solAssert(isTuple(m_type->category()), "");
solAssert(isTuple(*m_type), "");
}
SymbolicTupleVariable::SymbolicTupleVariable(
@ -274,7 +277,7 @@ SymbolicArrayVariable::SymbolicArrayVariable(
m_context
)
{
solAssert(isArray(m_type->category()) || isMapping(m_type->category()), "");
solAssert(isArray(*m_type) || isMapping(*m_type), "");
}
SymbolicArrayVariable::SymbolicArrayVariable(
@ -319,3 +322,47 @@ smtutil::Expression SymbolicArrayVariable::length()
{
return m_pair.component(1);
}
SymbolicStructVariable::SymbolicStructVariable(
frontend::TypePointer _type,
string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, move(_uniqueName), _context)
{
solAssert(isNonRecursiveStruct(*m_type), "");
auto const* structType = dynamic_cast<StructType const*>(_type);
solAssert(structType, "");
auto const& members = structType->structDefinition().members();
for (unsigned i = 0; i < members.size(); ++i)
{
solAssert(members.at(i), "");
m_memberIndices.emplace(members.at(i)->name(), i);
}
}
smtutil::Expression SymbolicStructVariable::member(string const& _member)
{
return smtutil::Expression::tuple_get(currentValue(), m_memberIndices.at(_member));
}
smtutil::Expression SymbolicStructVariable::assignMember(string const& _member, smtutil::Expression const& _memberValue)
{
auto const* structType = dynamic_cast<StructType const*>(m_type);
solAssert(structType, "");
auto const& structDef = structType->structDefinition();
auto const& structMembers = structDef.members();
auto oldMembers = applyMap(
structMembers,
[&](auto _member) { return member(_member->name()); }
);
increaseIndex();
for (unsigned i = 0; i < structMembers.size(); ++i)
{
auto const& memberName = structMembers.at(i)->name();
auto newMember = memberName == _member ? _memberValue : oldMembers.at(i);
m_context.addAssertion(member(memberName) == newMember);
}
return currentValue();
}

View File

@ -23,6 +23,8 @@
#include <libsolidity/ast/TypeProvider.h>
#include <libsmtutil/SolverInterface.h>
#include <map>
#include <memory>
namespace solidity::frontend::smt
@ -265,4 +267,29 @@ private:
SymbolicTupleVariable m_pair;
};
/**
* Specialization of SymbolicVariable for Struct.
*/
class SymbolicStructVariable: public SymbolicVariable
{
public:
SymbolicStructVariable(
frontend::TypePointer _type,
std::string _uniqueName,
EncodingContext& _context
);
/// @returns the symbolic expression representing _member.
smtutil::Expression member(std::string const& _member);
/// @returns the symbolic expression representing this struct
/// with field _member updated.
smtutil::Expression assignMember(std::string const& _member, smtutil::Expression const& _memberValue);
private:
std::map<std::string, unsigned> m_memberIndices;
};
}

View File

@ -11,10 +11,3 @@ contract C {
}
}
// ----
// Warning 6328: (119-157): Assertion violation happens here
// Warning 8115: (76-80): Assertion checker does not yet support the type of this variable.
// Warning 8115: (83-87): Assertion checker does not yet support the type of this variable.
// Warning 7650: (126-132): Assertion checker does not yet support this expression.
// Warning 8364: (126-128): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (143-149): Assertion checker does not yet support this expression.
// Warning 8364: (143-145): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -11,12 +11,3 @@ contract C {
}
}
// ----
// Warning 6328: (121-165): Assertion violation happens here
// Warning 8115: (78-82): Assertion checker does not yet support the type of this variable.
// Warning 8115: (85-89): Assertion checker does not yet support the type of this variable.
// Warning 7650: (128-134): Assertion checker does not yet support this expression.
// Warning 8364: (128-130): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9118: (128-137): Assertion checker does not yet implement this expression.
// Warning 7650: (148-154): Assertion checker does not yet support this expression.
// Warning 8364: (148-150): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9118: (148-157): Assertion checker does not yet implement this expression.

View File

@ -15,13 +15,3 @@ contract C {
}
// ----
// Warning 8115: (72-75): Assertion checker does not yet support the type of this variable.
// Warning 8115: (100-103): Assertion checker does not yet support the type of this variable.
// Warning 7650: (130-133): Assertion checker does not yet support this expression.
// Warning 8364: (130-131): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9599: (130-133): Assertion checker does not yet implement this expression.
// Warning 7650: (144-149): Assertion checker does not yet support this expression.
// Warning 8364: (144-147): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (144-147): Assertion checker does not yet support this expression.
// Warning 8364: (144-145): Assertion checker does not yet implement type struct C.T storage ref
// Warning 9599: (144-149): Assertion checker does not yet implement this expression.

View File

@ -16,18 +16,3 @@ contract C {
}
// ----
// Warning 8115: (72-75): Assertion checker does not yet support the type of this variable.
// Warning 8115: (102-105): Assertion checker does not yet support the type of this variable.
// Warning 7650: (132-135): Assertion checker does not yet support this expression.
// Warning 8364: (132-133): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9599: (132-135): Assertion checker does not yet implement this expression.
// Warning 7650: (146-149): Assertion checker does not yet support this expression.
// Warning 8364: (146-147): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (146-156): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9599: (146-149): Assertion checker does not yet implement this expression.
// Warning 7650: (160-168): Assertion checker does not yet support this expression.
// Warning 7650: (160-163): Assertion checker does not yet support this expression.
// Warning 8364: (160-161): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (160-166): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9118: (160-166): Assertion checker does not yet implement this expression.
// Warning 9599: (160-168): Assertion checker does not yet implement this expression.

View File

@ -118,23 +118,3 @@ contract PropagateThroughReturnValue {
}
// ----
// Warning 2018: (1879-1947): Function state mutability can be restricted to view
// Warning 8115: (318-332): Assertion checker does not yet support the type of this variable.
// Warning 8115: (338-347): Assertion checker does not yet support the type of this variable.
// Warning 8115: (353-378): Assertion checker does not yet support the type of this variable.
// Warning 8115: (384-409): Assertion checker does not yet support the type of this variable.
// Warning 7650: (464-479): Assertion checker does not yet support this expression.
// Warning 8364: (464-475): Assertion checker does not yet implement type struct Reference.St storage ref
// Warning 8182: (464-494): Assertion checker does not yet implement such assignments.
// Warning 7650: (539-554): Assertion checker does not yet support this expression.
// Warning 8364: (539-550): Assertion checker does not yet implement type struct Reference.St storage ref
// Warning 7650: (557-567): Assertion checker does not yet support this expression.
// Warning 8364: (557-563): Assertion checker does not yet implement type struct Reference.St storage ref
// Warning 8182: (539-567): Assertion checker does not yet implement such assignments.
// Warning 8115: (629-643): Assertion checker does not yet support the type of this variable.
// Warning 8364: (646-668): Assertion checker does not yet implement type struct Reference.St storage ref
// Warning 8364: (700-703): Assertion checker does not yet implement type struct Reference.St storage pointer
// Warning 8364: (706-728): Assertion checker does not yet implement type struct Reference.St storage ref
// Warning 8364: (700-728): Assertion checker does not yet implement type struct Reference.St storage pointer
// Warning 7650: (748-755): Assertion checker does not yet support this expression.
// Warning 8364: (748-751): Assertion checker does not yet implement type struct Reference.St storage pointer
// Warning 8182: (748-770): Assertion checker does not yet implement such assignments.

View File

@ -8,7 +8,5 @@ contract C {
}
// ----
// Warning 2072: (133-143): Unused local variable.
// Warning 8115: (133-143): Assertion checker does not yet support the type of this variable.
// Warning 8364: (146-147): Assertion checker does not yet implement type type(struct C.A storage pointer)
// Warning 8364: (146-163): Assertion checker does not yet implement type struct C.A memory
// Warning 4639: (146-163): Assertion checker does not yet implement this expression.

View File

@ -20,3 +20,4 @@ contract LoopFor2 {
}
// ----
// Warning 6328: (363-382): Assertion violation happens here
// Warning 4661: (316-336): Assertion violation happens here

View File

@ -21,3 +21,4 @@ contract LoopFor2 {
// ----
// Warning 6328: (341-360): Assertion violation happens here
// Warning 6328: (364-383): Assertion violation happens here
// Warning 4661: (317-337): Assertion violation happens here

View File

@ -10,7 +10,4 @@ contract C {
}
}
// ----
// Warning 8115: (71-74): Assertion checker does not yet support the type of this variable.
// Warning 7650: (117-120): Assertion checker does not yet support this expression.
// Warning 8364: (117-118): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9149: (117-125): Assertion checker does not yet implement this assignment operator.

View File

@ -10,8 +10,4 @@ contract C {
}
}
// ----
// Warning 8115: (73-76): Assertion checker does not yet support the type of this variable.
// Warning 7650: (119-122): Assertion checker does not yet support this expression.
// Warning 8364: (119-120): Assertion checker does not yet implement type struct C.S storage ref
// Warning 9118: (119-125): Assertion checker does not yet implement this expression.
// Warning 9149: (119-130): Assertion checker does not yet implement this assignment operator.

View File

@ -6,7 +6,7 @@ contract C
{
uint x;
}
function f(bool b) public {
function f(bool b) public pure {
S memory s;
s.x = 2;
if (b)
@ -17,15 +17,3 @@ contract C
}
}
// ----
// Warning 2018: (73-192): Function state mutability can be restricted to pure
// Warning 6328: (172-188): Assertion violation happens here
// Warning 8115: (103-113): Assertion checker does not yet support the type of this variable.
// Warning 7650: (117-120): Assertion checker does not yet support this expression.
// Warning 8364: (117-118): Assertion checker does not yet implement type struct C.S memory
// Warning 8182: (117-124): Assertion checker does not yet implement such assignments.
// Warning 8364: (145-146): Assertion checker does not yet implement type struct C.S memory
// Warning 7650: (165-168): Assertion checker does not yet support this expression.
// Warning 8364: (165-166): Assertion checker does not yet implement type struct C.S memory
// Warning 2683: (158-168): Assertion checker does not yet implement "delete" for this expression.
// Warning 7650: (179-182): Assertion checker does not yet support this expression.
// Warning 8364: (179-180): Assertion checker does not yet implement type struct C.S memory

View File

@ -0,0 +1,16 @@
pragma experimental SMTChecker;
contract C {
uint[] a;
function h() internal returns (uint[] storage) {
if (a[2] == 0)
a[2] = 3;
return a;
}
function g() public {
h()[2] = 4;
assert(h()[2] == 3);
}
}
// ----
// Warning 6328: (191-210): Assertion violation happens here

View File

@ -8,7 +8,6 @@ contract C {
}
}
// ----
// Warning 8115: (151-159): Assertion checker does not yet support the type of this variable.
// Warning 8364: (206-209): Assertion checker does not yet implement type abi
// Warning 8364: (225-226): Assertion checker does not yet implement type type(struct C.S storage pointer)
// Warning 8364: (235-241): Assertion checker does not yet implement type type(uint256[] memory)

View File

@ -14,19 +14,3 @@ contract C
}
}
// ----
// Warning 6328: (202-226): Assertion violation happens here
// Warning 7650: (124-130): Assertion checker does not yet support this expression.
// Warning 8364: (124-128): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (124-133): Assertion checker does not yet implement this expression.
// Warning 9056: (124-136): Assertion checker does not yet implement this expression.
// Warning 7650: (154-160): Assertion checker does not yet support this expression.
// Warning 8364: (154-158): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (154-163): Assertion checker does not yet implement this expression.
// Warning 9056: (154-166): Assertion checker does not yet implement this expression.
// Warning 7650: (182-188): Assertion checker does not yet support this expression.
// Warning 8364: (182-186): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (182-191): Assertion checker does not yet implement this expression.
// Warning 9056: (182-194): Assertion checker does not yet implement this expression.
// Warning 7650: (209-215): Assertion checker does not yet support this expression.
// Warning 8364: (209-213): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (209-218): Assertion checker does not yet implement this expression.

View File

@ -11,10 +11,3 @@ contract C
}
}
// ----
// Warning 6328: (187-208): Assertion violation happens here
// Warning 8115: (143-153): Assertion checker does not yet support the type of this variable.
// Warning 7650: (171-174): Assertion checker does not yet support this expression.
// Warning 8364: (171-172): Assertion checker does not yet implement type struct C.S memory
// Warning 8182: (171-183): Assertion checker does not yet implement such assignments.
// Warning 7650: (194-197): Assertion checker does not yet support this expression.
// Warning 8364: (194-195): Assertion checker does not yet implement type struct C.S memory

View File

@ -13,6 +13,5 @@ contract C {
}
}
// ----
// Warning 9118: (238-244): Assertion checker does not yet implement this expression.
// Warning 7989: (238-247): Assertion checker does not yet support index accessing fixed bytes.
// Warning 7989: (251-257): Assertion checker does not yet support index accessing fixed bytes.

View File

@ -12,8 +12,5 @@ contract C
}
// ----
// Warning 6838: (140-144): Condition is always false.
// Warning 8364: (149-156): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (159-160): Assertion checker does not yet implement type type(struct C.S storage pointer)
// Warning 8364: (159-163): Assertion checker does not yet implement type struct C.S memory
// Warning 4639: (159-163): Assertion checker does not yet implement this expression.
// Warning 8364: (149-163): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -17,7 +17,6 @@ contract test {
// Warning 6133: (156-163): Statement has no effect.
// Warning 8364: (125-126): Assertion checker does not yet implement type type(struct test.s storage pointer)
// Warning 8364: (130-131): Assertion checker does not yet implement type type(struct test.s storage pointer)
// Warning 8364: (130-136): Assertion checker does not yet implement type struct test.s memory
// Warning 4639: (130-136): Assertion checker does not yet implement this expression.
// Warning 8364: (140-141): Assertion checker does not yet implement type type(struct test.s storage pointer)
// Warning 8364: (140-144): Assertion checker does not yet implement type type(struct test.s memory[7] memory)

View File

@ -0,0 +1,30 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
function f() public pure {
S[] memory s1 = new S[](3);
s1[0].x = 2;
assert(s1[0].x == 2);
s1[1].t.y = 3;
assert(s1[1].t.y == 3);
s1[2].a[2] = 4;
assert(s1[2].a[2] == 4);
s1[0].ts[3].y = 5;
assert(s1[0].ts[3].y == 5);
s1[1].ts[4].a[5] = 6;
assert(s1[1].ts[4].a[5] == 6);
}
}
// ----
// Warning 4588: (217-227): Assertion checker does not yet implement this type of function call.

View File

@ -0,0 +1,35 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
function f(S memory s2) public pure {
S[] memory s1 = new S[](3);
s1[0].x = 2;
assert(s1[0].x == s2.x);
s1[1].t.y = 3;
assert(s1[1].t.y == s2.t.y);
s1[2].a[2] = 4;
assert(s1[2].a[2] == s2.a[2]);
s1[0].ts[3].y = 5;
assert(s1[0].ts[3].y == s2.ts[3].y);
s1[1].ts[4].a[5] = 6;
assert(s1[1].ts[4].a[5] == s2.ts[4].a[5]);
}
}
// ----
// Warning 6328: (257-280): Assertion violation happens here
// Warning 6328: (301-328): Assertion violation happens here
// Warning 6328: (350-379): Assertion violation happens here
// Warning 6328: (404-439): Assertion violation happens here
// Warning 6328: (467-508): Assertion violation happens here
// Warning 4588: (228-238): Assertion checker does not yet implement this type of function call.

View File

@ -0,0 +1,34 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
S[] s1;
function f() public {
s1.push();
s1.push();
s1.push();
s1[0].x = 2;
assert(s1[0].x == 2);
s1[1].t.y = 3;
assert(s1[1].t.y == 3);
s1[2].a[2] = 4;
assert(s1[2].a[2] == 4);
s1[0].ts[3].y = 5;
assert(s1[0].ts[3].y == 5);
s1[1].ts[4].a[5] = 6;
assert(s1[1].ts[4].a[5] == 6);
s1.pop();
s1.pop();
s1.pop();
}
}

View File

@ -0,0 +1,23 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint x;
uint[] a;
}
function f(S memory s1, S memory s2, bool b) public pure {
S memory s3 = b ? s1 : s2;
assert(s3.x == s1.x);
assert(s3.x == s2.x);
// This is safe.
assert(s3.x == s1.x || s3.x == s2.x);
// This fails as false positive because of lack of support to aliasing.
s3.x = 42;
assert(s3.x == s1.x || s3.x == s2.x);
}
}
// ----
// Warning 6328: (208-228): Assertion violation happens here
// Warning 6328: (232-252): Assertion violation happens here
// Warning 6328: (402-438): Assertion violation happens here

View File

@ -0,0 +1,30 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
uint[] a;
}
S s1;
S s2;
function f(bool b) public {
S storage s3 = b ? s1 : s2;
assert(s3.x == s1.x);
assert(s3.x == s2.x);
// This is safe.
assert(s3.x == s1.x || s3.x == s2.x);
// This fails as false positive because of lack of support to aliasing.
s3.x = 42;
assert(s3.x == s1.x || s3.x == s2.x);
}
function g(bool b, uint _x) public {
if (b)
s1.x = _x;
else
s2.x = _x;
}
}
// ----
// Warning 6328: (158-178): Assertion violation happens here
// Warning 6328: (182-202): Assertion violation happens here
// Warning 6328: (352-388): Assertion violation happens here

View File

@ -0,0 +1,28 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
function f() public pure {
S memory s1;
s1.x = 2;
assert(s1.x == 2);
s1.t.y = 3;
assert(s1.t.y == 3);
s1.a[2] = 4;
assert(s1.a[2] == 4);
s1.ts[3].y = 5;
assert(s1.ts[3].y == 5);
s1.ts[4].a[5] = 6;
assert(s1.ts[4].a[5] == 6);
}
}

View File

@ -0,0 +1,34 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
function f() public pure {
S memory s1;
s1.x = 2;
assert(s1.x != 2);
s1.t.y = 3;
assert(s1.t.y != 3);
s1.a[2] = 4;
assert(s1.a[2] != 4);
s1.ts[3].y = 5;
assert(s1.ts[3].y != 5);
s1.ts[4].a[5] = 6;
assert(s1.ts[4].a[5] != 6);
}
}
// ----
// Warning 6328: (228-245): Assertion violation happens here
// Warning 6328: (263-282): Assertion violation happens here
// Warning 6328: (301-321): Assertion violation happens here
// Warning 6328: (343-366): Assertion violation happens here
// Warning 6328: (391-417): Assertion violation happens here

View File

@ -0,0 +1,34 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
function f(S memory s2) public pure {
S memory s1;
s1.x = 2;
assert(s1.x == s2.x);
s1.t.y = 3;
assert(s1.t.y == s2.t.y);
s1.a[2] = 4;
assert(s1.a[2] == s2.a[2]);
s1.ts[3].y = 5;
assert(s1.ts[3].y == s2.ts[3].y);
s1.ts[4].a[5] = 6;
assert(s1.ts[4].a[5] == s2.ts[4].a[5]);
}
}
// ----
// Warning 6328: (239-259): Assertion violation happens here
// Warning 6328: (277-301): Assertion violation happens here
// Warning 6328: (320-346): Assertion violation happens here
// Warning 6328: (368-400): Assertion violation happens here
// Warning 6328: (425-463): Assertion violation happens here

View File

@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
S s1;
function f() public {
s1.x = 2;
assert(s1.x == 2);
s1.t.y = 3;
assert(s1.t.y == 3);
s1.a[2] = 4;
assert(s1.a[2] == 4);
s1.ts[3].y = 5;
assert(s1.ts[3].y == 5);
s1.ts[4].a[5] = 6;
assert(s1.ts[4].a[5] == 6);
}
}

View File

@ -0,0 +1,33 @@
pragma experimental SMTChecker;
contract C {
struct T {
uint y;
uint[] a;
}
struct S {
uint x;
T t;
uint[] a;
T[] ts;
}
S s1;
function f() public {
s1.x = 2;
assert(s1.x != 2);
s1.t.y = 3;
assert(s1.t.y != 3);
s1.a[2] = 4;
assert(s1.a[2] != 4);
s1.ts[3].y = 5;
assert(s1.ts[3].y != 5);
s1.ts[4].a[5] = 6;
assert(s1.ts[4].a[5] != 6);
}
}
// ----
// Warning 6328: (181-198): Assertion violation happens here
// Warning 6328: (216-235): Assertion violation happens here
// Warning 6328: (254-274): Assertion violation happens here
// Warning 6328: (296-319): Assertion violation happens here
// Warning 6328: (344-370): Assertion violation happens here.

View File

@ -0,0 +1,18 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint x;
uint[] a;
}
function f(S memory s1, S memory s2) public pure {
delete s1;
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
assert(s1.a.length == 0);
}
}
// ----
// Warning 6328: (184-204): Assertion violation happens here
// Warning 6328: (208-242): Assertion violation happens here

View File

@ -0,0 +1,23 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint x;
uint[] a;
}
S s1;
function g(S memory s2) public {
s1.x = s2.x;
s1.a = s2.a;
}
function f(S memory s2) public {
delete s1;
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
assert(s1.a.length == 0);
}
}
// ----
// Warning 6328: (240-260): Assertion violation happens here
// Warning 6328: (264-298): Assertion violation happens here

View File

@ -0,0 +1,18 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
mapping (uint => uint) m;
}
S s1;
S s2;
function f() public view {
assert(s1.m[0] == s2.m[0]);
}
function g(uint a, uint b) public {
s1.m[a] = b;
}
}
// ----
// Warning 4661: (143-169): Assertion violation happens here

View File

@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S s1;
S s2;
function f() public view {
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
}
}
// ----
// Warning 6328: (124-144): Assertion violation happens here
// Warning 6328: (148-182): Assertion violation happens here
// Warning 8115: (81-85): Assertion checker does not yet support the type of this variable.
// Warning 8115: (88-92): Assertion checker does not yet support the type of this variable.
// Warning 7650: (131-135): Assertion checker does not yet support this expression.
// Warning 8364: (131-133): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (139-143): Assertion checker does not yet support this expression.
// Warning 8364: (139-141): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (155-159): Assertion checker does not yet support this expression.
// Warning 8364: (155-157): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (170-174): Assertion checker does not yet support this expression.
// Warning 8364: (170-172): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -0,0 +1,69 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S s1;
S s2;
function f() public view {
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
assert(s1.a[0].x == s2.a[0].x);
}
function g() public {
s1.x = 42;
s2.x = 42;
s1.a.push();
s2.a.push();
s1.a[0].x = 43;
s2.a[0].x = 43;
}
}
// ----
// Warning 6328: (124-144): Assertion violation happens here
// Warning 6328: (148-182): Assertion violation happens here
// Warning 6328: (186-216): Assertion violation happens here
// Warning 8115: (81-85): Assertion checker does not yet support the type of this variable.
// Warning 8115: (88-92): Assertion checker does not yet support the type of this variable.
// Warning 7650: (131-135): Assertion checker does not yet support this expression.
// Warning 8364: (131-133): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (139-143): Assertion checker does not yet support this expression.
// Warning 8364: (139-141): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (155-159): Assertion checker does not yet support this expression.
// Warning 8364: (155-157): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (170-174): Assertion checker does not yet support this expression.
// Warning 8364: (170-172): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (193-202): Assertion checker does not yet support this expression.
// Warning 7650: (193-197): Assertion checker does not yet support this expression.
// Warning 8364: (193-195): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (193-200): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (206-215): Assertion checker does not yet support this expression.
// Warning 7650: (206-210): Assertion checker does not yet support this expression.
// Warning 8364: (206-208): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (206-213): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (246-250): Assertion checker does not yet support this expression.
// Warning 8364: (246-248): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (246-250): Assertion checker does not support recursive structs.
// Warning 7650: (259-263): Assertion checker does not yet support this expression.
// Warning 8364: (259-261): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (259-263): Assertion checker does not support recursive structs.
// Warning 7650: (272-276): Assertion checker does not yet support this expression.
// Warning 8364: (272-274): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (272-283): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (272-276): Assertion checker does not support recursive structs.
// Warning 7650: (287-291): Assertion checker does not yet support this expression.
// Warning 8364: (287-289): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (287-298): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (287-291): Assertion checker does not support recursive structs.
// Warning 7650: (302-311): Assertion checker does not yet support this expression.
// Warning 7650: (302-306): Assertion checker does not yet support this expression.
// Warning 8364: (302-304): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (302-309): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (302-311): Assertion checker does not support recursive structs.
// Warning 7650: (320-329): Assertion checker does not yet support this expression.
// Warning 7650: (320-324): Assertion checker does not yet support this expression.
// Warning 8364: (320-322): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (320-327): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (320-329): Assertion checker does not support recursive structs.

View File

@ -0,0 +1,123 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S s1;
S s2;
function f() public view {
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
assert(s1.a[0].x == s2.a[0].x);
assert(s1.a[0].a.length == s2.a[0].a.length);
assert(s1.a[0].a[0].x == s2.a[0].a[0].x);
}
function g() public {
s1.x = 42;
s2.x = 42;
s1.a.push();
s2.a.push();
s1.a[0].x = 43;
s2.a[0].x = 43;
s1.a[0].a.push();
s2.a[0].a.push();
s1.a[0].a[0].x = 44;
s2.a[0].a[0].x = 44;
}
}
// ----
// Warning 6328: (124-144): Assertion violation happens here
// Warning 6328: (148-182): Assertion violation happens here
// Warning 6328: (186-216): Assertion violation happens here
// Warning 6328: (220-264): Assertion violation happens here
// Warning 6328: (268-308): Assertion violation happens here
// Warning 8115: (81-85): Assertion checker does not yet support the type of this variable.
// Warning 8115: (88-92): Assertion checker does not yet support the type of this variable.
// Warning 7650: (131-135): Assertion checker does not yet support this expression.
// Warning 8364: (131-133): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (139-143): Assertion checker does not yet support this expression.
// Warning 8364: (139-141): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (155-159): Assertion checker does not yet support this expression.
// Warning 8364: (155-157): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (170-174): Assertion checker does not yet support this expression.
// Warning 8364: (170-172): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (193-202): Assertion checker does not yet support this expression.
// Warning 7650: (193-197): Assertion checker does not yet support this expression.
// Warning 8364: (193-195): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (193-200): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (206-215): Assertion checker does not yet support this expression.
// Warning 7650: (206-210): Assertion checker does not yet support this expression.
// Warning 8364: (206-208): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (206-213): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (227-236): Assertion checker does not yet support this expression.
// Warning 7650: (227-231): Assertion checker does not yet support this expression.
// Warning 8364: (227-229): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (227-234): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (247-256): Assertion checker does not yet support this expression.
// Warning 7650: (247-251): Assertion checker does not yet support this expression.
// Warning 8364: (247-249): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (247-254): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (275-289): Assertion checker does not yet support this expression.
// Warning 7650: (275-284): Assertion checker does not yet support this expression.
// Warning 7650: (275-279): Assertion checker does not yet support this expression.
// Warning 8364: (275-277): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (275-282): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (275-287): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (293-307): Assertion checker does not yet support this expression.
// Warning 7650: (293-302): Assertion checker does not yet support this expression.
// Warning 7650: (293-297): Assertion checker does not yet support this expression.
// Warning 8364: (293-295): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (293-300): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (293-305): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (338-342): Assertion checker does not yet support this expression.
// Warning 8364: (338-340): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (338-342): Assertion checker does not support recursive structs.
// Warning 7650: (351-355): Assertion checker does not yet support this expression.
// Warning 8364: (351-353): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (351-355): Assertion checker does not support recursive structs.
// Warning 7650: (364-368): Assertion checker does not yet support this expression.
// Warning 8364: (364-366): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (364-375): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (364-368): Assertion checker does not support recursive structs.
// Warning 7650: (379-383): Assertion checker does not yet support this expression.
// Warning 8364: (379-381): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (379-390): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (379-383): Assertion checker does not support recursive structs.
// Warning 7650: (394-403): Assertion checker does not yet support this expression.
// Warning 7650: (394-398): Assertion checker does not yet support this expression.
// Warning 8364: (394-396): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (394-401): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (394-403): Assertion checker does not support recursive structs.
// Warning 7650: (412-421): Assertion checker does not yet support this expression.
// Warning 7650: (412-416): Assertion checker does not yet support this expression.
// Warning 8364: (412-414): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (412-419): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (412-421): Assertion checker does not support recursive structs.
// Warning 7650: (430-439): Assertion checker does not yet support this expression.
// Warning 7650: (430-434): Assertion checker does not yet support this expression.
// Warning 8364: (430-432): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (430-437): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (430-446): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (430-439): Assertion checker does not support recursive structs.
// Warning 7650: (450-459): Assertion checker does not yet support this expression.
// Warning 7650: (450-454): Assertion checker does not yet support this expression.
// Warning 8364: (450-452): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (450-457): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (450-466): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (450-459): Assertion checker does not support recursive structs.
// Warning 7650: (470-484): Assertion checker does not yet support this expression.
// Warning 7650: (470-479): Assertion checker does not yet support this expression.
// Warning 7650: (470-474): Assertion checker does not yet support this expression.
// Warning 8364: (470-472): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (470-477): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (470-482): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (470-484): Assertion checker does not support recursive structs.
// Warning 7650: (493-507): Assertion checker does not yet support this expression.
// Warning 7650: (493-502): Assertion checker does not yet support this expression.
// Warning 7650: (493-497): Assertion checker does not yet support this expression.
// Warning 8364: (493-495): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (493-500): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (493-505): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (493-507): Assertion checker does not support recursive structs.

View File

@ -0,0 +1,56 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S s1;
S s2;
function f(bool b1, bool b2) public {
S storage s3 = b1 ? s1 : s2;
S storage s4 = b2 ? s1 : s2;
assert(s3.x == s1.x || s3.x == s2.x);
assert(s4.x == s1.x || s4.x == s2.x);
s3.x = 44;
// Fails as false positive because of lack of support to aliasing.
assert(s1.x == 44 || s2.x == 44);
}
}
// ----
// Warning 6328: (197-233): Assertion violation happens here
// Warning 6328: (237-273): Assertion violation happens here
// Warning 6328: (359-391): Assertion violation happens here
// Warning 8115: (81-85): Assertion checker does not yet support the type of this variable.
// Warning 8115: (88-92): Assertion checker does not yet support the type of this variable.
// Warning 8115: (135-147): Assertion checker does not yet support the type of this variable.
// Warning 8115: (166-178): Assertion checker does not yet support the type of this variable.
// Warning 8364: (155-157): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (160-162): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (150-162): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 8364: (186-188): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (191-193): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (181-193): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 7650: (204-208): Assertion checker does not yet support this expression.
// Warning 8364: (204-206): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 7650: (212-216): Assertion checker does not yet support this expression.
// Warning 8364: (212-214): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (220-224): Assertion checker does not yet support this expression.
// Warning 8364: (220-222): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 7650: (228-232): Assertion checker does not yet support this expression.
// Warning 8364: (228-230): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (244-248): Assertion checker does not yet support this expression.
// Warning 8364: (244-246): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 7650: (252-256): Assertion checker does not yet support this expression.
// Warning 8364: (252-254): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (260-264): Assertion checker does not yet support this expression.
// Warning 8364: (260-262): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 7650: (268-272): Assertion checker does not yet support this expression.
// Warning 8364: (268-270): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (277-281): Assertion checker does not yet support this expression.
// Warning 8364: (277-279): Assertion checker does not yet implement type struct C.S storage pointer
// Warning 4375: (277-281): Assertion checker does not support recursive structs.
// Warning 7650: (366-370): Assertion checker does not yet support this expression.
// Warning 8364: (366-368): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (380-384): Assertion checker does not yet support this expression.
// Warning 8364: (380-382): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -0,0 +1,29 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S[] sa;
S[][] sa2;
function f() public {
sa.push();
sa2.push();
sa2[0].push();
sa2[0][0].a.push();
assert(sa2[0][0].a.length == sa[0].a.length);
}
}
// ----
// Warning 6328: (192-236): Assertion violation happens here
// Warning 8364: (126-135): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (153-166): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (170-181): Assertion checker does not yet support this expression.
// Warning 8364: (170-179): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (170-188): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (170-181): Assertion checker does not support recursive structs.
// Warning 7650: (199-210): Assertion checker does not yet support this expression.
// Warning 8364: (199-208): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (221-228): Assertion checker does not yet support this expression.
// Warning 8364: (221-226): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -0,0 +1,66 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
S[] a;
}
S s1;
S s2;
function f() public {
s1.x = 10;
++s1.x;
s1.x++;
s2.x = 20;
--s2.x;
s2.x--;
assert(s1.x == s2.x + 6);
assert(s1.a.length == s2.a.length);
delete s1;
assert(s1.x == 0);
}
}
// ----
// Warning 4984: (200-208): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning 6328: (185-209): Assertion violation happens here
// Warning 6328: (213-247): Assertion violation happens here
// Warning 6328: (264-281): Assertion violation happens here
// Warning 8115: (81-85): Assertion checker does not yet support the type of this variable.
// Warning 8115: (88-92): Assertion checker does not yet support the type of this variable.
// Warning 7650: (119-123): Assertion checker does not yet support this expression.
// Warning 8364: (119-121): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (119-123): Assertion checker does not support recursive structs.
// Warning 7650: (134-138): Assertion checker does not yet support this expression.
// Warning 8364: (134-136): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (134-138): Assertion checker does not support recursive structs.
// Warning 7650: (142-146): Assertion checker does not yet support this expression.
// Warning 8364: (142-144): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (142-146): Assertion checker does not support recursive structs.
// Warning 7650: (152-156): Assertion checker does not yet support this expression.
// Warning 8364: (152-154): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (152-156): Assertion checker does not support recursive structs.
// Warning 7650: (167-171): Assertion checker does not yet support this expression.
// Warning 8364: (167-169): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (167-171): Assertion checker does not support recursive structs.
// Warning 7650: (175-179): Assertion checker does not yet support this expression.
// Warning 8364: (175-177): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (175-179): Assertion checker does not support recursive structs.
// Warning 7650: (192-196): Assertion checker does not yet support this expression.
// Warning 8364: (192-194): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (200-204): Assertion checker does not yet support this expression.
// Warning 8364: (200-202): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (220-224): Assertion checker does not yet support this expression.
// Warning 8364: (220-222): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (235-239): Assertion checker does not yet support this expression.
// Warning 8364: (235-237): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (258-260): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (271-275): Assertion checker does not yet support this expression.
// Warning 8364: (271-273): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4144: (132-138): Underflow (resulting value less than 0) happens here
// Warning 2661: (132-138): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning 4144: (142-148): Underflow (resulting value less than 0) happens here
// Warning 2661: (142-148): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning 4144: (165-171): Underflow (resulting value less than 0) happens here
// Warning 2661: (165-171): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning 4144: (175-181): Underflow (resulting value less than 0) happens here
// Warning 2661: (175-181): Overflow (resulting value larger than 2**256 - 1) happens here

View File

@ -0,0 +1,31 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
T[] a;
}
struct T {
uint y;
S[] a;
}
S s1;
S s2;
function f() public view {
assert(s1.x == s2.x);
assert(s1.a.length == s2.a.length);
}
}
// ----
// Warning 6328: (158-178): Assertion violation happens here
// Warning 6328: (182-216): Assertion violation happens here
// Warning 8115: (115-119): Assertion checker does not yet support the type of this variable.
// Warning 8115: (122-126): Assertion checker does not yet support the type of this variable.
// Warning 7650: (165-169): Assertion checker does not yet support this expression.
// Warning 8364: (165-167): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (173-177): Assertion checker does not yet support this expression.
// Warning 8364: (173-175): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (189-193): Assertion checker does not yet support this expression.
// Warning 8364: (189-191): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (204-208): Assertion checker does not yet support this expression.
// Warning 8364: (204-206): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -0,0 +1,57 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
T[] a;
}
struct T {
uint y;
S[] a;
}
S s1;
S s2;
function f() public {
s1.a.push();
s2.a.push();
s1.a[0].a.push();
s2.a[0].a.push();
assert(s1.a[0].a[0].x == s2.a[0].a[0].x);
}
}
// ----
// Warning 6328: (223-263): Assertion violation happens here
// Warning 8115: (115-119): Assertion checker does not yet support the type of this variable.
// Warning 8115: (122-126): Assertion checker does not yet support the type of this variable.
// Warning 7650: (153-157): Assertion checker does not yet support this expression.
// Warning 8364: (153-155): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (153-164): Assertion checker does not yet implement type struct C.T storage ref
// Warning 4375: (153-157): Assertion checker does not support recursive structs.
// Warning 7650: (168-172): Assertion checker does not yet support this expression.
// Warning 8364: (168-170): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (168-179): Assertion checker does not yet implement type struct C.T storage ref
// Warning 4375: (168-172): Assertion checker does not support recursive structs.
// Warning 7650: (183-192): Assertion checker does not yet support this expression.
// Warning 7650: (183-187): Assertion checker does not yet support this expression.
// Warning 8364: (183-185): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (183-190): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (183-199): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (183-192): Assertion checker does not support recursive structs.
// Warning 7650: (203-212): Assertion checker does not yet support this expression.
// Warning 7650: (203-207): Assertion checker does not yet support this expression.
// Warning 8364: (203-205): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (203-210): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (203-219): Assertion checker does not yet implement type struct C.S storage ref
// Warning 4375: (203-212): Assertion checker does not support recursive structs.
// Warning 7650: (230-244): Assertion checker does not yet support this expression.
// Warning 7650: (230-239): Assertion checker does not yet support this expression.
// Warning 7650: (230-234): Assertion checker does not yet support this expression.
// Warning 8364: (230-232): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (230-237): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (230-242): Assertion checker does not yet implement type struct C.S storage ref
// Warning 7650: (248-262): Assertion checker does not yet support this expression.
// Warning 7650: (248-257): Assertion checker does not yet support this expression.
// Warning 7650: (248-252): Assertion checker does not yet support this expression.
// Warning 8364: (248-250): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (248-255): Assertion checker does not yet implement type struct C.T storage ref
// Warning 8364: (248-260): Assertion checker does not yet implement type struct C.S storage ref

View File

@ -0,0 +1,20 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
uint[] a;
}
function s() internal pure returns (S memory s1) {
s1.x = 42;
s1.a[2] = 43;
}
function f() public pure {
S memory s2 = s();
assert(s2.x == 42);
assert(s2.a[2] == 43);
assert(s2.a[3] == 43);
}
}
// ----
// Warning 6328: (265-286): Assertion violation happens here

View File

@ -0,0 +1,16 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
uint[] a;
}
S s;
function f(uint _x) public {
s.x = _x;
s.a[0] = _x;
assert(s.a[1] == s.a[0]);
}
}
// ----
// Warning 6328: (148-172): Assertion violation happens here.

View File

@ -0,0 +1,25 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
uint[] a;
}
S s;
function f(uint _x) public {
s.a.pop();
s.a.length;
s.a.push();
s.x = _x;
s.a.pop();
s.a.push();
s.a.push();
s.a[0] = _x;
assert(s.a[1] == s.a[0]);
s.a.pop();
s.a.pop();
}
}
// ----
// Warning 2529: (121-130): Empty array "pop" detected here
// Warning 6328: (230-254): Assertion violation happens here

View File

@ -0,0 +1,22 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
uint[] a;
}
S s;
function f(uint _x) public {
s.x = _x;
s.a.pop();
s.a.push();
s.a.push();
s.a[0] = _x;
assert(s.a[1] == s.a[0]);
s.a.pop();
s.a.pop();
}
}
// ----
// Warning 2529: (133-142): Empty array "pop" detected here.
// Warning 6328: (189-213): Assertion violation happens here

View File

@ -0,0 +1,18 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint x;
uint[] a;
}
function f(S memory s1, S memory s2) public pure {
delete s1;
s1.x++;
++s1.x;
assert(s1.x == 2);
assert(s1.x == s2.x);
}
}
// ----
// Warning 6328: (225-245): Assertion violation happens here

View File

@ -0,0 +1,19 @@
pragma experimental SMTChecker;
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint x;
uint[] a;
}
function f(S memory s1, S memory s2) public pure {
delete s1;
s1.x = 100;
s1.x--;
--s1.x;
assert(s1.x == 98);
assert(s1.x == s2.x);
}
}
// ----
// Warning 6328: (240-260): Assertion violation happens here

View File

@ -15,12 +15,7 @@ contract C
}
// ----
// Warning 2072: (157-170): Unused local variable.
// Warning 8115: (157-170): Assertion checker does not yet support the type of this variable.
// Warning 8364: (139-146): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (149-150): Assertion checker does not yet implement type type(struct C.S storage pointer)
// Warning 8364: (149-153): Assertion checker does not yet implement type struct C.S memory
// Warning 4639: (149-153): Assertion checker does not yet implement this expression.
// Warning 8364: (139-153): Assertion checker does not yet implement type struct C.S storage ref
// Warning 8364: (173-174): Assertion checker does not yet implement type type(struct C.S storage pointer)
// Warning 8364: (173-177): Assertion checker does not yet implement type struct C.S memory
// Warning 4639: (173-177): Assertion checker does not yet implement this expression.

View File

@ -3,7 +3,7 @@ pragma experimental SMTChecker;
contract C
{
struct S { uint[] a; }
function f(bool b) public {
function f(bool b) public pure {
S memory c;
c.a[0] = 0;
if (b)
@ -14,21 +14,3 @@ contract C
}
}
// ----
// Warning 2018: (71-197): Function state mutability can be restricted to pure
// Warning 6328: (175-193): Assertion violation happens here
// Warning 8115: (101-111): Assertion checker does not yet support the type of this variable.
// Warning 7650: (115-118): Assertion checker does not yet support this expression.
// Warning 8364: (115-116): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (115-121): Assertion checker does not yet implement this expression.
// Warning 9056: (115-121): Assertion checker does not yet implement this expression.
// Warning 7650: (139-142): Assertion checker does not yet support this expression.
// Warning 8364: (139-140): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (139-145): Assertion checker does not yet implement this expression.
// Warning 9056: (139-145): Assertion checker does not yet implement this expression.
// Warning 7650: (161-164): Assertion checker does not yet support this expression.
// Warning 8364: (161-162): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (161-167): Assertion checker does not yet implement this expression.
// Warning 9056: (161-167): Assertion checker does not yet implement this expression.
// Warning 7650: (182-185): Assertion checker does not yet support this expression.
// Warning 8364: (182-183): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (182-188): Assertion checker does not yet implement this expression.

View File

@ -3,7 +3,7 @@ pragma experimental SMTChecker;
contract C
{
struct S { uint[][] a; }
function f(bool b) public {
function f(bool b) public pure {
S memory c;
c.a[0][0] = 0;
if (b)
@ -14,21 +14,3 @@ contract C
}
}
// ----
// Warning 2018: (73-211): Function state mutability can be restricted to pure
// Warning 6328: (186-207): Assertion violation happens here
// Warning 8115: (103-113): Assertion checker does not yet support the type of this variable.
// Warning 7650: (117-120): Assertion checker does not yet support this expression.
// Warning 8364: (117-118): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (117-123): Assertion checker does not yet implement this expression.
// Warning 9056: (117-126): Assertion checker does not yet implement this expression.
// Warning 7650: (144-147): Assertion checker does not yet support this expression.
// Warning 8364: (144-145): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (144-150): Assertion checker does not yet implement this expression.
// Warning 9056: (144-153): Assertion checker does not yet implement this expression.
// Warning 7650: (169-172): Assertion checker does not yet support this expression.
// Warning 8364: (169-170): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (169-175): Assertion checker does not yet implement this expression.
// Warning 9056: (169-178): Assertion checker does not yet implement this expression.
// Warning 7650: (193-196): Assertion checker does not yet support this expression.
// Warning 8364: (193-194): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (193-199): Assertion checker does not yet implement this expression.

View File

@ -14,20 +14,3 @@ contract C
}
}
// ----
// Warning 6328: (202-226): Assertion violation happens here
// Warning 8115: (110-120): Assertion checker does not yet support the type of this variable.
// Warning 7650: (124-127): Assertion checker does not yet support this expression.
// Warning 8364: (124-125): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (124-130): Assertion checker does not yet implement this expression.
// Warning 9056: (124-136): Assertion checker does not yet implement this expression.
// Warning 7650: (154-157): Assertion checker does not yet support this expression.
// Warning 8364: (154-155): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (154-160): Assertion checker does not yet implement this expression.
// Warning 9056: (154-166): Assertion checker does not yet implement this expression.
// Warning 7650: (182-185): Assertion checker does not yet support this expression.
// Warning 8364: (182-183): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (182-188): Assertion checker does not yet implement this expression.
// Warning 9056: (182-194): Assertion checker does not yet implement this expression.
// Warning 7650: (209-212): Assertion checker does not yet support this expression.
// Warning 8364: (209-210): Assertion checker does not yet implement type struct C.S memory
// Warning 9118: (209-215): Assertion checker does not yet implement this expression.

View File

@ -14,11 +14,6 @@ contract C {
}
}
// ----
// Warning 8115: (112-120): Assertion checker does not yet support the type of this variable.
// Warning 8364: (137-138): Assertion checker does not yet implement type type(struct C.S storage pointer)
// Warning 8364: (137-141): Assertion checker does not yet implement type struct C.S memory
// Warning 4639: (137-141): Assertion checker does not yet implement this expression.
// Warning 8115: (193-203): Assertion checker does not yet support the type of this variable.
// Warning 8364: (227-228): Assertion checker does not yet implement type struct C.S memory
// Warning 4639: (137-141): Assertion checker does not yet implement this expression.
// Warning 6191: (227-228): Assertion checker does not yet implement type struct C.S memory