| 5441 | |
| 5442 | template<class Key, class F> |
| 5443 | static bool productParams(const Settings& settings, const std::unordered_map<Key, std::list<ValueFlow::Value>>& vars, F f) |
| 5444 | { |
| 5445 | using Args = std::vector<std::unordered_map<Key, ValueFlow::Value>>; |
| 5446 | Args args(1); |
| 5447 | // Compute cartesian product of all arguments |
| 5448 | for (const auto& p : vars) { |
| 5449 | if (p.second.empty()) |
| 5450 | continue; |
| 5451 | args.back()[p.first] = p.second.front(); |
| 5452 | } |
| 5453 | bool bail = false; |
| 5454 | int max = settings.vfOptions.maxSubFunctionArgs; |
| 5455 | for (const auto& p : vars) { |
| 5456 | if (args.size() > max) { |
| 5457 | bail = true; |
| 5458 | break; |
| 5459 | } |
| 5460 | if (p.second.empty()) |
| 5461 | continue; |
| 5462 | std::for_each(std::next(p.second.begin()), p.second.end(), [&](const ValueFlow::Value& value) { |
| 5463 | Args new_args; |
| 5464 | for (auto arg : args) { |
| 5465 | if (value.path != 0) { |
| 5466 | for (const auto& q : arg) { |
| 5467 | if (q.first == p.first) |
| 5468 | continue; |
| 5469 | if (q.second.path == 0) |
| 5470 | continue; |
| 5471 | if (q.second.path != value.path) |
| 5472 | return; |
| 5473 | } |
| 5474 | } |
| 5475 | arg[p.first] = value; |
| 5476 | new_args.push_back(std::move(arg)); |
| 5477 | } |
| 5478 | std::copy(new_args.cbegin(), new_args.cend(), std::back_inserter(args)); |
| 5479 | }); |
| 5480 | } |
| 5481 | |
| 5482 | if (args.size() > max) { |
| 5483 | bail = true; |
| 5484 | args.resize(max); |
| 5485 | // TODO: add bailout message |
| 5486 | } |
| 5487 | |
| 5488 | for (const auto& arg : args) { |
| 5489 | if (arg.empty()) |
| 5490 | continue; |
| 5491 | // Make sure all arguments are the same path |
| 5492 | const MathLib::bigint path = arg.cbegin()->second.path; |
| 5493 | if (std::any_of(arg.cbegin(), arg.cend(), [&](const std::pair<Key, ValueFlow::Value>& p) { |
| 5494 | return p.second.path != path; |
| 5495 | })) |
| 5496 | continue; |
| 5497 | f(arg); |
| 5498 | } |
| 5499 | return !bail; |
| 5500 | } |