| 979 | } |
| 980 | |
| 981 | void CHC::externalFunctionCall(FunctionCall const& _funCall) |
| 982 | { |
| 983 | /// In external function calls we do not add a "predicate call" |
| 984 | /// because we do not trust their function body anyway, |
| 985 | /// so we just add the nondet_interface predicate. |
| 986 | |
| 987 | solAssert(m_currentContract, ""); |
| 988 | |
| 989 | auto [callExpr, callOptions] = functionCallExpression(_funCall); |
| 990 | FunctionType const& funType = dynamic_cast<FunctionType const&>(*callExpr->annotation().type); |
| 991 | |
| 992 | auto kind = funType.kind(); |
| 993 | solAssert( |
| 994 | kind == FunctionType::Kind::External || |
| 995 | kind == FunctionType::Kind::BareCall || |
| 996 | kind == FunctionType::Kind::BareStaticCall, |
| 997 | "" |
| 998 | ); |
| 999 | |
| 1000 | |
| 1001 | // Only consider high level external calls in trusted mode. |
| 1002 | if ( |
| 1003 | kind == FunctionType::Kind::External && |
| 1004 | (encodeExternalCallsAsTrusted() || isExternalCallToThis(callExpr)) |
| 1005 | ) |
| 1006 | { |
| 1007 | externalFunctionCallToTrustedCode(_funCall); |
| 1008 | return; |
| 1009 | } |
| 1010 | |
| 1011 | // Low level calls are still encoded nondeterministically. |
| 1012 | |
| 1013 | auto function = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract); |
| 1014 | if (function) |
| 1015 | for (auto var: function->returnParameters()) |
| 1016 | m_context.variable(*var)->increaseIndex(); |
| 1017 | |
| 1018 | // If we see a low level call in trusted mode, |
| 1019 | // we need to havoc the global state. |
| 1020 | if ( |
| 1021 | kind == FunctionType::Kind::BareCall && |
| 1022 | encodeExternalCallsAsTrusted() |
| 1023 | ) |
| 1024 | state().newStorage(); |
| 1025 | |
| 1026 | // No reentrancy from constructor calls. |
| 1027 | if (!m_currentFunction || m_currentFunction->isConstructor()) |
| 1028 | return; |
| 1029 | |
| 1030 | if (Expression const* value = valueOption(callOptions)) |
| 1031 | decreaseBalanceFromOptionsValue(*value); |
| 1032 | |
| 1033 | auto preCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables(); |
| 1034 | |
| 1035 | if (!usesStaticCall(_funCall)) |
| 1036 | { |
| 1037 | state().newState(); |
| 1038 | for (auto const* var: m_stateVariables) |
nothing calls this directly
no test coverage detected