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

Method checkConstFunc

lib/checkclass.cpp:2487–2759  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2485}
2486
2487bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, MemberAccess& memberAccessed) const
2488{
2489 if (mTokenizer->hasIfdef(func->functionScope->bodyStart, func->functionScope->bodyEnd))
2490 return false;
2491
2492 auto getFuncTok = [](const Token* tok) -> const Token* {
2493 if (Token::simpleMatch(tok, "this"))
2494 tok = getFuncTokFromThis(tok);
2495 bool isReturn = false;
2496 if ((Token::Match(tok, "%name% (|{") || (isReturn = Token::simpleMatch(tok->astParent(), "return {"))) && !tok->isStandardType() && !tok->isKeyword()) {
2497 if (isReturn)
2498 tok = tok->astParent();
2499 return tok;
2500 }
2501 return nullptr;
2502 };
2503
2504 auto checkFuncCall = [this, &memberAccessed](const Token* funcTok, const Scope* scope, const Function* func) {
2505 if (isMemberFunc(scope, funcTok) && (funcTok->strAt(-1) != "." || Token::simpleMatch(funcTok->tokAt(-2), "this ."))) {
2506 const bool isSelf = func == funcTok->function();
2507 if (!isConstMemberFunc(scope, funcTok) && !isSelf)
2508 return false;
2509 memberAccessed = (isSelf && memberAccessed != MemberAccess::MEMBER) ? MemberAccess::SELF : MemberAccess::MEMBER;
2510 }
2511
2512 if (const Function* f = funcTok->function()) { // check known function
2513 const std::vector<const Token*> args = getArguments(funcTok);
2514 const auto argMax = std::min<nonneg int>(args.size(), f->argCount());
2515
2516 for (nonneg int argIndex = 0; argIndex < argMax; ++argIndex) {
2517 const Variable* const argVar = f->getArgumentVar(argIndex);
2518 if (!argVar || ((argVar->isArrayOrPointer() || argVar->isReference()) &&
2519 !(argVar->valueType() && argVar->valueType()->isConst(argVar->valueType()->pointer)))) { // argument might be modified
2520 const Token* arg = args[argIndex];
2521 // Member variable given as parameter
2522 while (Token::simpleMatch(arg, "(") && arg->astOperand2())
2523 arg = arg->astOperand2();
2524 const Token* varTok = previousBeforeAstLeftmostLeaf(arg);
2525 if (!varTok)
2526 return false;
2527 varTok = varTok->next();
2528 if ((varTok->isName() && isMemberVar(scope, varTok)) || (varTok->isUnaryOp("&") && (varTok = varTok->astOperand1()) && isMemberVar(scope, varTok))) {
2529 const Variable* var = varTok->variable();
2530 if (!var || (!var->isMutable() && !var->isConst()))
2531 return false;
2532 }
2533 }
2534 }
2535 return true;
2536 }
2537
2538 if (const Library::Function* fLib = mSettings.library.getFunction(funcTok))
2539 if (fLib->isconst || fLib->ispure)
2540 return true;
2541
2542 // Member variable given as parameter to unknown function
2543 const Token *lpar = funcTok->next();
2544 if (Token::simpleMatch(lpar, "( ) ("))

Callers

nothing calls this directly

Calls 15

getFuncTokFromThisFunction · 0.85
isNonConstPtrCastFunction · 0.85
containsFunction · 0.85
isLikelyStreamReadFunction · 0.85
hasIfdefMethod · 0.80
astParentMethod · 0.80
getArgumentVarMethod · 0.80
isArrayOrPointerMethod · 0.80
isConstMethod · 0.80
astOperand2Method · 0.80

Tested by

no test coverage detected