| 5635 | } |
| 5636 | |
| 5637 | static void valueFlowLibraryFunction(Token* tok, const std::string& returnValue, const Settings& settings) |
| 5638 | { |
| 5639 | std::unordered_map<nonneg int, std::list<ValueFlow::Value>> argValues; |
| 5640 | int argn = 1; |
| 5641 | for (const Token* argtok : getArguments(tok->previous())) { |
| 5642 | argValues[argn] = getFunctionArgumentValues(argtok); |
| 5643 | argn++; |
| 5644 | } |
| 5645 | if (returnValue.find("arg") != std::string::npos && argValues.empty()) |
| 5646 | return; |
| 5647 | productParams(settings, argValues, [&](const std::unordered_map<nonneg int, ValueFlow::Value>& arg) { |
| 5648 | ValueFlow::Value value = evaluateLibraryFunction(arg, returnValue, settings, tok->isCpp()); |
| 5649 | if (value.isUninitValue()) |
| 5650 | return; |
| 5651 | ValueFlow::Value::ValueKind kind = ValueFlow::Value::ValueKind::Known; |
| 5652 | for (auto&& p : arg) { |
| 5653 | if (p.second.isPossible()) |
| 5654 | kind = p.second.valueKind; |
| 5655 | if (p.second.isInconclusive()) { |
| 5656 | kind = p.second.valueKind; |
| 5657 | break; |
| 5658 | } |
| 5659 | } |
| 5660 | if (value.isImpossible() && kind != ValueFlow::Value::ValueKind::Known) |
| 5661 | return; |
| 5662 | if (!value.isImpossible()) |
| 5663 | value.valueKind = kind; |
| 5664 | setTokenValue(tok, std::move(value), settings); |
| 5665 | }); |
| 5666 | } |
| 5667 | |
| 5668 | static void valueFlowSubFunction(const TokenList& tokenlist, |
| 5669 | const SymbolDatabase& symboldatabase, |
no test coverage detected