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

Function getFunctionUsage

lib/astutils.cpp:3426–3502  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3424}
3425
3426static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings& settings)
3427{
3428 const bool addressOf = tok->astParent() && tok->astParent()->isUnaryOp("&");
3429
3430 int argnr;
3431 const Token* ftok = getTokenArgumentFunction(tok, argnr);
3432 if (!ftok)
3433 return ExprUsage::None;
3434 const Function* func = ftok->function();
3435 // variable init/constructor call?
3436 if (!func && ftok->variable() && ftok == ftok->variable()->nameToken()) {
3437 // STL types or containers don't initialize external variables
3438 if (indirect == 0 && (ftok->variable()->isStlType() || (ftok->variable()->valueType() && ftok->variable()->valueType()->container)))
3439 return ExprUsage::Used;
3440 // TODO: resolve multiple constructors
3441 if (ftok->variable()->type() && ftok->variable()->type()->classScope) {
3442 const int nCtor = ftok->variable()->type()->classScope->numConstructors;
3443 if (nCtor == 0) {
3444 if (indirect > 0) {
3445 const std::vector<const Variable*> argvar = getArgumentVars(ftok->astParent(), argnr);
3446 if (argvar.size() == 1 && argvar[0]->valueType() && argvar[0]->valueType()->pointer == indirect)
3447 return ExprUsage::NotUsed;
3448 }
3449 return ExprUsage::Used;
3450 }
3451 if (nCtor == 1) {
3452 const Scope* scope = ftok->variable()->type()->classScope;
3453 auto it = std::find_if(scope->functionList.begin(), scope->functionList.end(), [](const Function& f) {
3454 return f.isConstructor();
3455 });
3456 if (it != scope->functionList.end())
3457 func = &*it;
3458 }
3459 }
3460 }
3461 if (func) {
3462 std::vector<const Variable*> args = getArgumentVars(ftok, argnr);
3463 for (const Variable* arg : args) {
3464 if (!arg)
3465 continue;
3466 if (arg->isReference() || (arg->isPointer() && indirect == 1)) {
3467 if (!func->hasBody())
3468 return ExprUsage::PassedByReference;
3469 for (const Token* bodytok = func->functionScope->bodyStart; bodytok != func->functionScope->bodyEnd; bodytok = bodytok->next()) {
3470 if (bodytok->variable() == arg) {
3471 if (arg->isReference())
3472 return ExprUsage::PassedByReference;
3473 if (Token::Match(bodytok->astParent(), "%comp%|!"))
3474 return ExprUsage::NotUsed;
3475 return ExprUsage::PassedByReference;
3476 }
3477 }
3478 return ExprUsage::NotUsed;
3479 }
3480 }
3481 if (!args.empty() && indirect == 0 && !addressOf)
3482 return ExprUsage::Used;
3483 } else if (ftok->isControlFlowKeyword()) {

Callers 1

getExprUsageFunction · 0.85

Calls 15

getTokenArgumentFunctionFunction · 0.85
getArgumentVarsFunction · 0.85
astIsPointerFunction · 0.85
astParentMethod · 0.80
isUnaryOpMethod · 0.80
variableMethod · 0.80
typeMethod · 0.80
nextMethod · 0.80
isnullargbadMethod · 0.80
isuninitargbadMethod · 0.80
getArgDirectionMethod · 0.80
functionMethod · 0.45

Tested by

no test coverage detected