mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[SMTChecker] Fix literal string type mismatch
This commit is contained in:
parent
f5f2bbb274
commit
360f868836
@ -14,6 +14,7 @@ Compiler Features:
|
||||
* Standard JSON Interface: Compile only selected sources and contracts.
|
||||
* Standard JSON Interface: Provide secondary error locations (e.g. the source position of other conflicting declarations).
|
||||
* SMTChecker: Do not erase knowledge about storage pointers if another storage pointer is assigned.
|
||||
* SMTChecker: Support string literal type.
|
||||
* Standard JSON Interface: Provide AST even on errors if ``--error-recovery`` commandline switch or StandardCompiler `settings.parserErrorRecovery` is true.
|
||||
* Yul Optimizer: Do not inline function if it would result in expressions being duplicated that are not cheap.
|
||||
|
||||
@ -29,6 +30,7 @@ Bugfixes:
|
||||
* SMTChecker: Fix internal error when inlining a function that returns a tuple containing an unsupported type inside a branch.
|
||||
* SMTChecker: Fix internal error when inlining functions that use state variables and belong to a different source.
|
||||
* SMTChecker: Fix internal error when reporting counterexamples concerning state variables from different source files.
|
||||
* SMTChecker: Fix SMT sort mismatch when using string literals.
|
||||
* View/Pure Checker: Properly detect state variable access through base class.
|
||||
* Yul analyzer: Check availability of data objects already in analysis phase.
|
||||
* Yul Optimizer: Fix an issue where memory-accessing code was removed even though ``msize`` was used in the program.
|
||||
|
@ -187,7 +187,7 @@ void SMTEncoder::endVisit(VariableDeclarationStatement const& _varDecl)
|
||||
declarations.at(i) &&
|
||||
m_context.knownVariable(*declarations.at(i))
|
||||
)
|
||||
assignment(*declarations.at(i), components.at(i)->currentValue());
|
||||
assignment(*declarations.at(i), components.at(i)->currentValue(declarations.at(i)->type()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,30 +235,43 @@ void SMTEncoder::endVisit(Assignment const& _assignment)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const& type = _assignment.annotation().type;
|
||||
vector<smt::Expression> rightArguments;
|
||||
if (_assignment.rightHandSide().annotation().type->category() == Type::Category::Tuple)
|
||||
{
|
||||
auto symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_assignment.rightHandSide()));
|
||||
solAssert(symbTuple, "");
|
||||
for (auto const& component: symbTuple->components())
|
||||
auto symbTupleLeft = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_assignment.leftHandSide()));
|
||||
solAssert(symbTupleLeft, "");
|
||||
auto symbTupleRight = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_assignment.rightHandSide()));
|
||||
solAssert(symbTupleRight, "");
|
||||
|
||||
auto const& leftComponents = symbTupleLeft->components();
|
||||
auto const& rightComponents = symbTupleRight->components();
|
||||
solAssert(leftComponents.size() == rightComponents.size(), "");
|
||||
|
||||
for (unsigned i = 0; i < leftComponents.size(); ++i)
|
||||
{
|
||||
auto const& left = leftComponents.at(i);
|
||||
auto const& right = rightComponents.at(i);
|
||||
/// Right hand side tuple component cannot be empty.
|
||||
solAssert(component, "");
|
||||
rightArguments.push_back(component->currentValue());
|
||||
solAssert(right, "");
|
||||
if (left)
|
||||
rightArguments.push_back(right->currentValue(left->originalType()));
|
||||
else
|
||||
rightArguments.push_back(right->currentValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rightHandSide = compoundOps.count(op) ?
|
||||
compoundAssignment(_assignment) :
|
||||
expr(_assignment.rightHandSide());
|
||||
expr(_assignment.rightHandSide(), type);
|
||||
defineExpr(_assignment, rightHandSide);
|
||||
rightArguments.push_back(expr(_assignment));
|
||||
rightArguments.push_back(expr(_assignment, type));
|
||||
}
|
||||
assignment(
|
||||
_assignment.leftHandSide(),
|
||||
rightArguments,
|
||||
_assignment.annotation().type,
|
||||
type,
|
||||
_assignment.location()
|
||||
);
|
||||
}
|
||||
@ -620,16 +633,10 @@ void SMTEncoder::endVisit(Literal const& _literal)
|
||||
defineExpr(_literal, smt::Expression(type.literalValue(&_literal)));
|
||||
else if (smt::isBool(type.category()))
|
||||
defineExpr(_literal, smt::Expression(_literal.token() == Token::TrueLiteral ? true : false));
|
||||
else if (smt::isStringLiteral(type.category()))
|
||||
createExpr(_literal);
|
||||
else
|
||||
{
|
||||
if (type.category() == Type::Category::StringLiteral)
|
||||
{
|
||||
auto stringType = TypeProvider::stringMemory();
|
||||
auto stringLit = dynamic_cast<StringLiteralType const*>(_literal.annotation().type);
|
||||
solAssert(stringLit, "");
|
||||
auto result = smt::newSymbolicVariable(*stringType, stringLit->richIdentifier(), m_context);
|
||||
m_context.createExpression(_literal, result.second);
|
||||
}
|
||||
m_errorReporter.warning(
|
||||
_literal.location(),
|
||||
"Assertion checker does not yet support the type of this literal (" +
|
||||
@ -653,7 +660,7 @@ void SMTEncoder::endVisit(Return const& _return)
|
||||
for (unsigned i = 0; i < returnParams.size(); ++i)
|
||||
{
|
||||
solAssert(components.at(i), "");
|
||||
m_context.addAssertion(components.at(i)->currentValue() == m_context.newValue(*returnParams.at(i)));
|
||||
m_context.addAssertion(components.at(i)->currentValue(returnParams.at(i)->type()) == m_context.newValue(*returnParams.at(i)));
|
||||
}
|
||||
}
|
||||
else if (returnParams.size() == 1)
|
||||
@ -957,14 +964,15 @@ pair<smt::Expression, smt::Expression> SMTEncoder::arithmeticOperation(
|
||||
|
||||
void SMTEncoder::compareOperation(BinaryOperation const& _op)
|
||||
{
|
||||
solAssert(_op.annotation().commonType, "");
|
||||
if (smt::isSupportedType(_op.annotation().commonType->category()))
|
||||
auto const& commonType = _op.annotation().commonType;
|
||||
solAssert(commonType, "");
|
||||
if (smt::isSupportedType(commonType->category()))
|
||||
{
|
||||
smt::Expression left(expr(_op.leftExpression()));
|
||||
smt::Expression right(expr(_op.rightExpression()));
|
||||
smt::Expression left(expr(_op.leftExpression(), commonType));
|
||||
smt::Expression right(expr(_op.rightExpression(), commonType));
|
||||
Token op = _op.getOperator();
|
||||
shared_ptr<smt::Expression> value;
|
||||
if (smt::isNumber(_op.annotation().commonType->category()))
|
||||
if (smt::isNumber(commonType->category()))
|
||||
{
|
||||
value = make_shared<smt::Expression>(
|
||||
op == Token::Equal ? (left == right) :
|
||||
@ -977,7 +985,7 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
|
||||
}
|
||||
else // Bool
|
||||
{
|
||||
solUnimplementedAssert(smt::isBool(_op.annotation().commonType->category()), "Operation not yet supported");
|
||||
solUnimplementedAssert(smt::isBool(commonType->category()), "Operation not yet supported");
|
||||
value = make_shared<smt::Expression>(
|
||||
op == Token::Equal ? (left == right) :
|
||||
/*op == Token::NotEqual*/ (left != right)
|
||||
@ -1104,7 +1112,7 @@ smt::Expression SMTEncoder::compoundAssignment(Assignment const& _assignment)
|
||||
|
||||
void SMTEncoder::assignment(VariableDeclaration const& _variable, Expression const& _value)
|
||||
{
|
||||
assignment(_variable, expr(_value));
|
||||
assignment(_variable, expr(_value, _variable.type()));
|
||||
}
|
||||
|
||||
void SMTEncoder::assignment(VariableDeclaration const& _variable, smt::Expression const& _value)
|
||||
@ -1258,14 +1266,15 @@ bool SMTEncoder::createVariable(VariableDeclaration const& _varDecl)
|
||||
return true;
|
||||
}
|
||||
|
||||
smt::Expression SMTEncoder::expr(Expression const& _e)
|
||||
smt::Expression SMTEncoder::expr(Expression const& _e, TypePointer _targetType)
|
||||
{
|
||||
if (!m_context.knownExpression(_e))
|
||||
{
|
||||
m_errorReporter.warning(_e.location(), "Internal error: Expression undefined for SMT solver." );
|
||||
createExpr(_e);
|
||||
}
|
||||
return m_context.expression(_e)->currentValue();
|
||||
|
||||
return m_context.expression(_e)->currentValue(_targetType);
|
||||
}
|
||||
|
||||
void SMTEncoder::createExpr(Expression const& _e)
|
||||
|
@ -175,8 +175,10 @@ protected:
|
||||
/// @returns an expression denoting the value of the variable declared in @a _decl
|
||||
/// at the given index. Does not ensure that this index exists.
|
||||
smt::Expression valueAtIndex(VariableDeclaration const& _decl, int _index);
|
||||
/// Returns the expression corresponding to the AST node. Throws if the expression does not exist.
|
||||
smt::Expression expr(Expression const& _e);
|
||||
/// Returns the expression corresponding to the AST node.
|
||||
/// If _targetType is not null apply conversion.
|
||||
/// Throws if the expression does not exist.
|
||||
smt::Expression expr(Expression const& _e, TypePointer _targetType = nullptr);
|
||||
/// Creates the expression (value can be arbitrary)
|
||||
void createExpr(Expression const& _e);
|
||||
/// Creates the expression and sets its value.
|
||||
|
@ -64,6 +64,13 @@ SortPointer smtSort(solidity::Type const& _type)
|
||||
solAssert(mapType, "");
|
||||
return make_shared<ArraySort>(smtSort(*mapType->keyType()), smtSort(*mapType->valueType()));
|
||||
}
|
||||
else if (isStringLiteral(_type.category()))
|
||||
{
|
||||
auto stringLitType = dynamic_cast<solidity::StringLiteralType const*>(&_type);
|
||||
solAssert(stringLitType, "");
|
||||
auto intSort = make_shared<Sort>(Kind::Int);
|
||||
return make_shared<ArraySort>(intSort, intSort);
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(isArray(_type.category()), "");
|
||||
@ -127,19 +134,19 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
|
||||
if (!isSupportedTypeDeclaration(_type))
|
||||
{
|
||||
abstract = true;
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), _uniqueName, _context);
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), type, _uniqueName, _context);
|
||||
}
|
||||
else if (isBool(_type.category()))
|
||||
var = make_shared<SymbolicBoolVariable>(type, _uniqueName, _context);
|
||||
else if (isFunction(_type.category()))
|
||||
var = make_shared<SymbolicFunctionVariable>(type, _uniqueName, _context);
|
||||
else if (isInteger(_type.category()))
|
||||
var = make_shared<SymbolicIntVariable>(type, _uniqueName, _context);
|
||||
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
|
||||
else if (isFixedBytes(_type.category()))
|
||||
{
|
||||
auto fixedBytesType = dynamic_cast<solidity::FixedBytesType const*>(type);
|
||||
solAssert(fixedBytesType, "");
|
||||
var = make_shared<SymbolicFixedBytesVariable>(fixedBytesType->numBytes(), _uniqueName, _context);
|
||||
var = make_shared<SymbolicFixedBytesVariable>(type, fixedBytesType->numBytes(), _uniqueName, _context);
|
||||
}
|
||||
else if (isAddress(_type.category()) || isContract(_type.category()))
|
||||
var = make_shared<SymbolicAddressVariable>(_uniqueName, _context);
|
||||
@ -150,16 +157,21 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
|
||||
auto rational = dynamic_cast<solidity::RationalNumberType const*>(&_type);
|
||||
solAssert(rational, "");
|
||||
if (rational->isFractional())
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), _uniqueName, _context);
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), type, _uniqueName, _context);
|
||||
else
|
||||
var = make_shared<SymbolicIntVariable>(type, _uniqueName, _context);
|
||||
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
|
||||
}
|
||||
else if (isMapping(_type.category()))
|
||||
var = make_shared<SymbolicMappingVariable>(type, _uniqueName, _context);
|
||||
else if (isArray(_type.category()))
|
||||
var = make_shared<SymbolicArrayVariable>(type, _uniqueName, _context);
|
||||
var = make_shared<SymbolicArrayVariable>(type, type, _uniqueName, _context);
|
||||
else if (isTuple(_type.category()))
|
||||
var = make_shared<SymbolicTupleVariable>(type, _uniqueName, _context);
|
||||
else if (isStringLiteral(_type.category()))
|
||||
{
|
||||
auto stringType = TypeProvider::stringMemory();
|
||||
var = make_shared<SymbolicArrayVariable>(stringType, type, _uniqueName, _context);
|
||||
}
|
||||
else
|
||||
solAssert(false, "");
|
||||
return make_pair(abstract, var);
|
||||
@ -232,7 +244,8 @@ bool isMapping(solidity::Type::Category _category)
|
||||
|
||||
bool isArray(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == solidity::Type::Category::Array;
|
||||
return _category == solidity::Type::Category::Array ||
|
||||
_category == solidity::Type::Category::StringLiteral;
|
||||
}
|
||||
|
||||
bool isTuple(solidity::Type::Category _category)
|
||||
@ -240,6 +253,11 @@ bool isTuple(solidity::Type::Category _category)
|
||||
return _category == solidity::Type::Category::Tuple;
|
||||
}
|
||||
|
||||
bool isStringLiteral(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == solidity::Type::Category::StringLiteral;
|
||||
}
|
||||
|
||||
Expression minValue(solidity::IntegerType const& _type)
|
||||
{
|
||||
return Expression(_type.minValue());
|
||||
|
@ -54,6 +54,7 @@ bool isFunction(solidity::Type::Category _category);
|
||||
bool isMapping(solidity::Type::Category _category);
|
||||
bool isArray(solidity::Type::Category _category);
|
||||
bool isTuple(solidity::Type::Category _category);
|
||||
bool isStringLiteral(solidity::Type::Category _category);
|
||||
|
||||
/// Returns a new symbolic variable, according to _type.
|
||||
/// Also returns whether the type is abstract or not,
|
||||
|
@ -27,10 +27,12 @@ using namespace dev::solidity::smt;
|
||||
|
||||
SymbolicVariable::SymbolicVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalType,
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
m_type(move(_type)),
|
||||
m_type(_type),
|
||||
m_originalType(_originalType),
|
||||
m_uniqueName(move(_uniqueName)),
|
||||
m_context(_context),
|
||||
m_ssa(make_unique<SSAVariable>())
|
||||
@ -53,7 +55,7 @@ SymbolicVariable::SymbolicVariable(
|
||||
solAssert(m_sort, "");
|
||||
}
|
||||
|
||||
Expression SymbolicVariable::currentValue() const
|
||||
Expression SymbolicVariable::currentValue(solidity::TypePointer const&) const
|
||||
{
|
||||
return valueAtIndex(m_ssa->index());
|
||||
}
|
||||
@ -95,17 +97,18 @@ SymbolicBoolVariable::SymbolicBoolVariable(
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _type, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(m_type->category() == solidity::Type::Category::Bool, "");
|
||||
}
|
||||
|
||||
SymbolicIntVariable::SymbolicIntVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalType,
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _originalType, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(isNumber(m_type->category()), "");
|
||||
}
|
||||
@ -114,16 +117,17 @@ SymbolicAddressVariable::SymbolicAddressVariable(
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicIntVariable(TypeProvider::uint(160), move(_uniqueName), _context)
|
||||
SymbolicIntVariable(TypeProvider::uint(160), TypeProvider::uint(160), move(_uniqueName), _context)
|
||||
{
|
||||
}
|
||||
|
||||
SymbolicFixedBytesVariable::SymbolicFixedBytesVariable(
|
||||
solidity::TypePointer _originalType,
|
||||
unsigned _numBytes,
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicIntVariable(TypeProvider::uint(_numBytes * 8), move(_uniqueName), _context)
|
||||
SymbolicIntVariable(TypeProvider::uint(_numBytes * 8), _originalType, move(_uniqueName), _context)
|
||||
{
|
||||
}
|
||||
|
||||
@ -132,7 +136,7 @@ SymbolicFunctionVariable::SymbolicFunctionVariable(
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context),
|
||||
SymbolicVariable(_type, _type, move(_uniqueName), _context),
|
||||
m_declaration(m_context.newVariable(currentName(), m_sort))
|
||||
{
|
||||
solAssert(m_type->category() == solidity::Type::Category::Function, "");
|
||||
@ -171,27 +175,41 @@ SymbolicMappingVariable::SymbolicMappingVariable(
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _type, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(isMapping(m_type->category()), "");
|
||||
}
|
||||
|
||||
SymbolicArrayVariable::SymbolicArrayVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalType,
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _originalType, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(isArray(m_type->category()), "");
|
||||
}
|
||||
|
||||
Expression SymbolicArrayVariable::currentValue(solidity::TypePointer const& _targetType) const
|
||||
{
|
||||
if (_targetType)
|
||||
// StringLiterals are encoded as SMT arrays in the generic case,
|
||||
// but they can also be compared/assigned to fixed bytes, in which
|
||||
// case they'd need to be encoded as numbers.
|
||||
if (auto strType = dynamic_cast<StringLiteralType const*>(m_originalType))
|
||||
if (_targetType->category() == solidity::Type::Category::FixedBytes)
|
||||
return smt::Expression(u256(toHex(asBytes(strType->value()), HexPrefix::Add)));
|
||||
|
||||
return SymbolicVariable::currentValue(_targetType);
|
||||
}
|
||||
|
||||
SymbolicEnumVariable::SymbolicEnumVariable(
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _type, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(isEnum(m_type->category()), "");
|
||||
}
|
||||
@ -201,7 +219,7 @@ SymbolicTupleVariable::SymbolicTupleVariable(
|
||||
string _uniqueName,
|
||||
EncodingContext& _context
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _context)
|
||||
SymbolicVariable(_type, _type, move(_uniqueName), _context)
|
||||
{
|
||||
solAssert(isTuple(m_type->category()), "");
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ class SymbolicVariable
|
||||
public:
|
||||
SymbolicVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalType,
|
||||
std::string _uniqueName,
|
||||
EncodingContext& _context
|
||||
);
|
||||
@ -51,7 +52,7 @@ public:
|
||||
|
||||
virtual ~SymbolicVariable() = default;
|
||||
|
||||
Expression currentValue() const;
|
||||
virtual Expression currentValue(solidity::TypePointer const& _targetType = TypePointer{}) const;
|
||||
std::string currentName() const;
|
||||
virtual Expression valueAtIndex(int _index) const;
|
||||
virtual std::string nameAtIndex(int _index) const;
|
||||
@ -67,6 +68,7 @@ public:
|
||||
|
||||
SortPointer const& sort() const { return m_sort; }
|
||||
solidity::TypePointer const& type() const { return m_type; }
|
||||
solidity::TypePointer const& originalType() const { return m_originalType; }
|
||||
|
||||
protected:
|
||||
std::string uniqueSymbol(unsigned _index) const;
|
||||
@ -75,6 +77,8 @@ protected:
|
||||
SortPointer m_sort;
|
||||
/// Solidity type, used for size and range in number types.
|
||||
solidity::TypePointer m_type;
|
||||
/// Solidity original type, used for type conversion if necessary.
|
||||
solidity::TypePointer m_originalType;
|
||||
std::string m_uniqueName;
|
||||
EncodingContext& m_context;
|
||||
std::unique_ptr<SSAVariable> m_ssa;
|
||||
@ -101,6 +105,7 @@ class SymbolicIntVariable: public SymbolicVariable
|
||||
public:
|
||||
SymbolicIntVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalType,
|
||||
std::string _uniqueName,
|
||||
EncodingContext& _context
|
||||
);
|
||||
@ -125,6 +130,7 @@ class SymbolicFixedBytesVariable: public SymbolicIntVariable
|
||||
{
|
||||
public:
|
||||
SymbolicFixedBytesVariable(
|
||||
solidity::TypePointer _originalType,
|
||||
unsigned _numBytes,
|
||||
std::string _uniqueName,
|
||||
EncodingContext& _context
|
||||
@ -180,9 +186,12 @@ class SymbolicArrayVariable: public SymbolicVariable
|
||||
public:
|
||||
SymbolicArrayVariable(
|
||||
solidity::TypePointer _type,
|
||||
solidity::TypePointer _originalTtype,
|
||||
std::string _uniqueName,
|
||||
EncodingContext& _context
|
||||
);
|
||||
|
||||
Expression currentValue(solidity::TypePointer const& _targetType = TypePointer{}) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -53,9 +53,6 @@ contract MyConc{
|
||||
// ----
|
||||
// Warning: (773-792): This declaration shadows an existing declaration.
|
||||
// Warning: (1009-1086): Function state mutability can be restricted to view
|
||||
// Warning: (327-332): Assertion checker does not yet support the type of this literal (literal_string "abc").
|
||||
// Warning: (353-358): Assertion checker does not yet support the type of this literal (literal_string "xyz").
|
||||
// Warning: (834-839): Assertion checker does not yet support the type of this literal (literal_string "abc").
|
||||
// Warning: (874-879): Underflow (resulting value less than 0) happens here.
|
||||
// Warning: (874-879): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning: (985-1002): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
|
@ -83,7 +83,6 @@ contract InternalCall {
|
||||
// Warning: (1144-1206): Function state mutability can be restricted to pure
|
||||
// Warning: (1212-1274): Function state mutability can be restricted to pure
|
||||
// Warning: (1280-1342): Function state mutability can be restricted to pure
|
||||
// Warning: (799-811): Assertion checker does not yet support the type of this literal (literal_string "helloTwo()").
|
||||
// Warning: (782-813): Type conversion is not yet fully supported and might yield false positives.
|
||||
// Warning: (771-814): Assertion checker does not yet implement this type of function call.
|
||||
// Warning: (825-830): Assertion checker does not yet support the type of this variable.
|
||||
|
@ -6,7 +6,5 @@ contract C {
|
||||
}
|
||||
// ----
|
||||
// Warning: (31-64): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||
// Warning: (173-175): Assertion checker does not yet support the type of this literal (literal_string "").
|
||||
// Warning: (162-176): Assertion checker does not yet implement this type of function call.
|
||||
// Warning: (196-202): Assertion checker does not yet support the type of this literal (literal_string "7?8r").
|
||||
// Warning: (178-203): Assertion checker does not yet implement this type of function call.
|
||||
|
@ -8,4 +8,3 @@ contract C
|
||||
}
|
||||
// ----
|
||||
// Warning: (76-91): Unused local variable.
|
||||
// Warning: (94-107): Assertion checker does not yet support the type of this literal (literal_string "Hello World").
|
||||
|
@ -0,0 +1,13 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
bytes32 y = "test";
|
||||
bytes16 z = "testz";
|
||||
assert(_x == y);
|
||||
assert(_x == z);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (175-190): Assertion violation happens here
|
@ -0,0 +1,12 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
(bytes32 y, bytes16 z) = ("test", "testz");
|
||||
assert(_x == y);
|
||||
assert(_x == z);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (176-191): Assertion violation happens here
|
@ -0,0 +1,14 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
bytes32 y;
|
||||
bytes16 z;
|
||||
(y, z) = ("test", "testz");
|
||||
assert(_x == y);
|
||||
assert(_x == z);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (186-201): Assertion violation happens here
|
@ -0,0 +1,18 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function g() internal pure returns (bytes32, bytes16) {
|
||||
return ("test", "testz");
|
||||
}
|
||||
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
bytes32 y;
|
||||
bytes16 z;
|
||||
(y, z) = g();
|
||||
assert(_x == y);
|
||||
assert(_x == z);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (261-276): Assertion violation happens here
|
@ -0,0 +1,16 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function g() internal pure returns (bytes32, bytes16) {
|
||||
return ("test", "testz");
|
||||
}
|
||||
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
(bytes32 y, bytes16 z) = g();
|
||||
assert(_x == y);
|
||||
assert(_x == z);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (251-266): Assertion violation happens here
|
@ -0,0 +1,13 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x == "test");
|
||||
bytes32 y = _x;
|
||||
bytes32 z = _x;
|
||||
assert(z == "test");
|
||||
assert(y == "testx");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (170-190): Assertion violation happens here
|
@ -0,0 +1,13 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bytes32 _x) public pure {
|
||||
require(_x != "test");
|
||||
bytes32 y = _x;
|
||||
bytes32 z = _x;
|
||||
assert(z == "test");
|
||||
assert(y != "testx");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (147-166): Assertion violation happens here
|
@ -6,4 +6,3 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (97-125): Assertion checker does not yet support the type of this literal (literal_string "Input number is too large.").
|
||||
|
Loading…
Reference in New Issue
Block a user