mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix 1-tuple chain
This commit is contained in:
parent
ba4e05c62c
commit
9d2a0947e9
@ -31,6 +31,7 @@ Compiler Features:
|
||||
Bugfixes:
|
||||
* NatSpec: Constructors and functions have consistent userdoc output.
|
||||
* Inheritance: Disallow public state variables overwriting ``pure`` functions.
|
||||
* SMTChecker: Fix internal error when assigning to a 1-tuple.
|
||||
* State Mutability: Constant public state variables are considered ``pure`` functions.
|
||||
|
||||
|
||||
|
@ -425,17 +425,13 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple)
|
||||
auto const& symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_tuple));
|
||||
solAssert(symbTuple, "");
|
||||
auto const& symbComponents = symbTuple->components();
|
||||
auto const* tupleComponents = &_tuple.components();
|
||||
while (tupleComponents->size() == 1)
|
||||
{
|
||||
auto innerTuple = dynamic_pointer_cast<TupleExpression>(tupleComponents->front());
|
||||
solAssert(innerTuple, "");
|
||||
tupleComponents = &innerTuple->components();
|
||||
}
|
||||
solAssert(symbComponents.size() == tupleComponents->size(), "");
|
||||
auto const* tuple = dynamic_cast<TupleExpression const*>(innermostTuple(_tuple));
|
||||
solAssert(tuple, "");
|
||||
auto const& tupleComponents = tuple->components();
|
||||
solAssert(symbComponents.size() == tupleComponents.size(), "");
|
||||
for (unsigned i = 0; i < symbComponents.size(); ++i)
|
||||
{
|
||||
auto tComponent = tupleComponents->at(i);
|
||||
auto tComponent = tupleComponents.at(i);
|
||||
if (tComponent)
|
||||
{
|
||||
if (auto varDecl = identifierToVariable(*tComponent))
|
||||
@ -454,8 +450,7 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple)
|
||||
/// Parenthesized expressions are also TupleExpression regardless their type.
|
||||
auto const& components = _tuple.components();
|
||||
solAssert(components.size() == 1, "");
|
||||
if (smt::isSupportedType(components.front()->annotation().type->category()))
|
||||
defineExpr(_tuple, expr(*components.front()));
|
||||
defineExpr(_tuple, expr(*components.front()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -729,11 +724,7 @@ void SMTEncoder::visitGasLeft(FunctionCall const& _funCall)
|
||||
|
||||
void SMTEncoder::endVisit(Identifier const& _identifier)
|
||||
{
|
||||
if (_identifier.annotation().willBeWrittenTo)
|
||||
{
|
||||
// Will be translated as part of the node that requested the lvalue.
|
||||
}
|
||||
else if (auto decl = identifierToVariable(_identifier))
|
||||
if (auto decl = identifierToVariable(_identifier))
|
||||
defineExpr(_identifier, currentValue(*decl));
|
||||
else if (_identifier.annotation().type->category() == Type::Category::Function)
|
||||
visitFunctionIdentifier(_identifier);
|
||||
@ -1449,10 +1440,14 @@ void SMTEncoder::assignment(
|
||||
"Tuple assignments should be handled by tupleAssignment."
|
||||
);
|
||||
|
||||
Expression const* left = &_left;
|
||||
if (auto const* tuple = dynamic_cast<TupleExpression const*>(left))
|
||||
left = innermostTuple(*tuple);
|
||||
|
||||
if (!smt::isSupportedType(_type->category()))
|
||||
{
|
||||
// Give it a new index anyway to keep the SSA scheme sound.
|
||||
if (auto varDecl = identifierToVariable(_left))
|
||||
if (auto varDecl = identifierToVariable(*left))
|
||||
m_context.newValue(*varDecl);
|
||||
|
||||
m_errorReporter.warning(
|
||||
@ -1461,10 +1456,10 @@ void SMTEncoder::assignment(
|
||||
"Assertion checker does not yet implement type " + _type->toString()
|
||||
);
|
||||
}
|
||||
else if (auto varDecl = identifierToVariable(_left))
|
||||
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))
|
||||
arrayIndexAssignment(*left, _right);
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
8182_error,
|
||||
@ -1901,6 +1896,20 @@ Expression const* SMTEncoder::leftmostBase(IndexAccess const& _indexAccess)
|
||||
return base;
|
||||
}
|
||||
|
||||
Expression const* SMTEncoder::innermostTuple(TupleExpression const& _tuple)
|
||||
{
|
||||
solAssert(!_tuple.isInlineArray(), "");
|
||||
TupleExpression const* tuple = &_tuple;
|
||||
Expression const* expr = tuple;
|
||||
while (tuple && !tuple->isInlineArray() && tuple->components().size() == 1)
|
||||
{
|
||||
expr = tuple->components().front().get();
|
||||
tuple = dynamic_cast<TupleExpression const*>(expr);
|
||||
}
|
||||
solAssert(expr, "");
|
||||
return expr;
|
||||
}
|
||||
|
||||
set<VariableDeclaration const*> SMTEncoder::touchedVariables(ASTNode const& _node)
|
||||
{
|
||||
vector<CallableDeclaration const*> callStack;
|
||||
|
@ -54,6 +54,9 @@ public:
|
||||
/// @returns the leftmost identifier in a multi-d IndexAccess.
|
||||
static Expression const* leftmostBase(IndexAccess const& _indexAccess);
|
||||
|
||||
/// @returns the innermost element in a chain of 1-tuples.
|
||||
static Expression const* innermostTuple(TupleExpression const& _tuple);
|
||||
|
||||
/// @returns the FunctionDefinition of a FunctionCall
|
||||
/// if possible or nullptr.
|
||||
static FunctionDefinition const* functionCallToDefinition(FunctionCall const& _funCall);
|
||||
|
@ -132,6 +132,7 @@ contract PropagateThroughReturnValue {
|
||||
// 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.
|
||||
|
@ -13,7 +13,8 @@ contract C
|
||||
assert(x > 0);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// SMTSolvers: cvc4
|
||||
// ----
|
||||
// Warning 1218: (296-309): Error trying to invoke SMT solver.
|
||||
// Warning 2661: (176-181): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4661: (296-309): Assertion violation happens here
|
||||
|
@ -22,6 +22,7 @@ contract C
|
||||
// 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.
|
||||
|
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_1.sol
Normal file
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_1.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function i() public pure returns (uint d) {
|
||||
if (0==0)
|
||||
(d) = 13;
|
||||
assert(d == 13);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6838: (96-100): Condition is always true.
|
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_2.sol
Normal file
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_2.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function i() public pure returns (uint d) {
|
||||
if (0==0)
|
||||
((d)) = 13;
|
||||
assert(d == 13);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6838: (96-100): Condition is always true.
|
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_n.sol
Normal file
10
test/libsolidity/smtCheckerTests/types/tuple_1_chain_n.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function i() public pure returns (uint d) {
|
||||
if (0==0)
|
||||
(((((d))))) = 13;
|
||||
assert(d == 13);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6838: (96-100): Condition is always true.
|
@ -19,5 +19,6 @@ contract C {
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user