MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / valueFlowSubFunction

Function valueFlowSubFunction

lib/valueflow.cpp:5668–5747  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5666}
5667
5668static void valueFlowSubFunction(const TokenList& tokenlist,
5669 const SymbolDatabase& symboldatabase,
5670 ErrorLogger& errorLogger,
5671 const Settings& settings)
5672{
5673 int id = 0;
5674 for (auto it = symboldatabase.functionScopes.crbegin(); it != symboldatabase.functionScopes.crend(); ++it) {
5675 const Scope* scope = *it;
5676 const Function* function = scope->function;
5677 if (!function)
5678 continue;
5679 for (auto* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
5680 if (tok->isKeyword() || !Token::Match(tok, "%name% ("))
5681 continue;
5682
5683 const Function* const calledFunction = tok->function();
5684 if (!calledFunction) {
5685 // library function?
5686 const std::string& returnValue(settings.library.returnValue(tok));
5687 if (!returnValue.empty())
5688 valueFlowLibraryFunction(tok->next(), returnValue, settings);
5689 continue;
5690 }
5691
5692 const Scope* const calledFunctionScope = calledFunction->functionScope;
5693 if (!calledFunctionScope)
5694 continue;
5695
5696 id++;
5697 std::unordered_map<const Variable*, std::list<ValueFlow::Value>> argvars;
5698 // TODO: Rewrite this. It does not work well to inject 1 argument at a time.
5699 const std::vector<const Token*>& callArguments = getArguments(tok);
5700 for (int argnr = 0U; argnr < callArguments.size(); ++argnr) {
5701 const Token* argtok = callArguments[argnr];
5702 // Get function argument
5703 const Variable* const argvar = calledFunction->getArgumentVar(argnr);
5704 if (!argvar)
5705 break;
5706
5707 // passing value(s) to function
5708 std::list<ValueFlow::Value> argvalues(getFunctionArgumentValues(argtok));
5709
5710 // Remove non-local lifetimes
5711 argvalues.remove_if([](const ValueFlow::Value& v) {
5712 if (v.isLifetimeValue())
5713 return !v.isLocalLifetimeValue() && !v.isSubFunctionLifetimeValue();
5714 return false;
5715 });
5716 // Remove uninit values if argument is passed by value
5717 if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 &&
5718 argvalues.front().isUninitValue()) {
5719 if (CheckUninitVarImpl::isVariableUsage(argtok, settings.library, false, CheckUninitVarImpl::Alloc::NO_ALLOC, 0))
5720 continue;
5721 }
5722
5723 if (argvalues.empty())
5724 continue;
5725

Callers 1

setValuesMethod · 0.85

Calls 15

valueFlowLibraryFunctionFunction · 0.85
isVariableUsageFunction · 0.85
getOrdinalTextFunction · 0.85
lowerToPossibleFunction · 0.85
valueFlowInjectParameterFunction · 0.85
nextMethod · 0.80
getArgumentVarMethod · 0.80
variableMethod · 0.80
frontMethod · 0.80
infoStringMethod · 0.80
getArgumentsFunction · 0.70

Tested by

no test coverage detected