@@ -1635,7 +1635,7 @@ void SMTEncoder::arrayPop(FunctionCall const& _funCall)
16351635
16361636void SMTEncoder::arrayPushPopAssign (Expression const & _expr, smtutil::Expression const & _array)
16371637{
1638- Expression const * expr = innermostTuple (_expr);
1638+ Expression const * expr = cleanExpression (_expr);
16391639
16401640 if (auto const * id = dynamic_cast <Identifier const *>(expr))
16411641 {
@@ -1654,8 +1654,10 @@ void SMTEncoder::arrayPushPopAssign(Expression const& _expr, smtutil::Expression
16541654 indexOrMemberAssignment (_expr, _array);
16551655 else if (auto const * funCall = dynamic_cast <FunctionCall const *>(expr))
16561656 {
1657- FunctionType const & funType = dynamic_cast <FunctionType const &>(*funCall->expression ().annotation ().type );
1658- if (funType.kind () == FunctionType::Kind::ArrayPush)
1657+ if (
1658+ auto funType = dynamic_cast <FunctionType const *>(funCall->expression ().annotation ().type );
1659+ funType && funType->kind () == FunctionType::Kind::ArrayPush
1660+ )
16591661 {
16601662 auto memberAccess = dynamic_cast <MemberAccess const *>(&funCall->expression ());
16611663 solAssert (memberAccess, " " );
@@ -2608,6 +2610,33 @@ Expression const* SMTEncoder::innermostTuple(Expression const& _expr)
26082610 return expr;
26092611}
26102612
2613+ Expression const * SMTEncoder::cleanExpression (Expression const & _expr)
2614+ {
2615+ auto const * expr = &_expr;
2616+ if (auto const * tuple = dynamic_cast <TupleExpression const *>(expr))
2617+ return cleanExpression (*innermostTuple (*tuple));
2618+ if (auto const * functionCall = dynamic_cast <FunctionCall const *>(expr))
2619+ if (*functionCall->annotation ().kind == FunctionCallKind::TypeConversion)
2620+ {
2621+ auto typeType = dynamic_cast <TypeType const *>(functionCall->expression ().annotation ().type );
2622+ solAssert (typeType, " " );
2623+ if (auto const * arrayType = dynamic_cast <ArrayType const *>(typeType->actualType ()))
2624+ if (arrayType->isByteArray ())
2625+ {
2626+ // this is a cast to `bytes`
2627+ solAssert (functionCall->arguments ().size () == 1 , " " );
2628+ Expression const & arg = *functionCall->arguments ()[0 ];
2629+ if (
2630+ auto const * argArrayType = dynamic_cast <ArrayType const *>(arg.annotation ().type );
2631+ argArrayType && argArrayType->isByteArray ()
2632+ )
2633+ return cleanExpression (arg);
2634+ }
2635+ }
2636+ solAssert (expr, " " );
2637+ return expr;
2638+ }
2639+
26112640set<VariableDeclaration const *> SMTEncoder::touchedVariables (ASTNode const & _node)
26122641{
26132642 vector<CallableDeclaration const *> callStack;
0 commit comments