| 2641 | } |
| 2642 | |
| 2643 | static void valueFlowLifetimeClassConstructor(Token* tok, |
| 2644 | const Type* t, |
| 2645 | const TokenList& tokenlist, |
| 2646 | ErrorLogger& errorLogger, |
| 2647 | const Settings& settings) |
| 2648 | { |
| 2649 | if (!Token::Match(tok, "(|{")) |
| 2650 | return; |
| 2651 | if (isScope(tok)) |
| 2652 | return; |
| 2653 | if (!t) { |
| 2654 | if (tok->valueType() && tok->valueType()->type != ValueType::RECORD) |
| 2655 | return; |
| 2656 | if (tok->str() != "{" && !Token::Match(tok->previous(), "%var% (") && !isVariableDecl(tok->previous())) |
| 2657 | return; |
| 2658 | // If the type is unknown then assume it captures by value in the |
| 2659 | // constructor, but make each lifetime inconclusive |
| 2660 | std::vector<const Token*> args = getArguments(tok); |
| 2661 | LifetimeStore::forEach(tokenlist, |
| 2662 | errorLogger, |
| 2663 | settings, |
| 2664 | args, |
| 2665 | "Passed to initializer list.", |
| 2666 | ValueFlow::Value::LifetimeKind::SubObject, |
| 2667 | [&](LifetimeStore& ls) { |
| 2668 | ls.inconclusive = true; |
| 2669 | ls.byVal(tok, tokenlist, errorLogger, settings); |
| 2670 | }); |
| 2671 | return; |
| 2672 | } |
| 2673 | const Scope* scope = t->classScope; |
| 2674 | if (!scope) |
| 2675 | return; |
| 2676 | // Aggregate constructor |
| 2677 | if (t->derivedFrom.empty() && (t->isClassType() || t->isStructType())) { |
| 2678 | std::vector<const Token*> args = getArguments(tok); |
| 2679 | if (scope->numConstructors == 0) { |
| 2680 | auto it = scope->varlist.cbegin(); |
| 2681 | LifetimeStore::forEach( |
| 2682 | tokenlist, |
| 2683 | errorLogger, |
| 2684 | settings, |
| 2685 | args, |
| 2686 | "Passed to constructor of '" + t->name() + "'.", |
| 2687 | ValueFlow::Value::LifetimeKind::SubObject, |
| 2688 | [&](LifetimeStore& ls) { |
| 2689 | const bool isDesignatedInitializerArg = isDesignatedInitializer(ls.argtok->astOperand1()); |
| 2690 | // Skip static variable |
| 2691 | it = std::find_if(it, scope->varlist.cend(), [&](const Variable &var) { |
| 2692 | if (var.isStatic()) |
| 2693 | return false; |
| 2694 | if (!isDesignatedInitializerArg) |
| 2695 | return true; |
| 2696 | return var.name() == ls.argtok->astOperand1()->astOperand1()->str(); |
| 2697 | }); |
| 2698 | if (it == scope->varlist.cend()) |
| 2699 | return; |
| 2700 | if (isDesignatedInitializerArg) |
no test coverage detected