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

Method autoVariables

lib/checkautovariables.cpp:283–344  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

281}
282
283void CheckAutoVariablesImpl::autoVariables()
284{
285 logChecker("CheckAutoVariables::autoVariables");
286
287 const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive);
288 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
289 for (const Scope * scope : symbolDatabase->functionScopes) {
290 for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
291 // Skip lambda..
292 if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
293 tok = lambdaEndToken;
294 continue;
295 }
296 // Critical assignment
297 const Token* rhs{};
298 if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings)) {
299 checkAutoVariableAssignment(tok->next(), false);
300 } else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings)) {
301 const Token* lhs = tok->tokAt(2);
302 bool inconclusive = false;
303 if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive))
304 checkAutoVariableAssignment(tok->next(), inconclusive);
305 tok = tok->tokAt(4);
306 } else if (isMemberAssignment(tok, rhs, mSettings)) {
307 const Token* lhs = tok->tokAt(3);
308 bool inconclusive = false;
309 if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive))
310 checkAutoVariableAssignment(tok->next(), inconclusive);
311 tok = rhs;
312 } else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") &&
313 (isPtrArg(tok->next()) || isArrayArg(tok->next(), mSettings)) &&
314 isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings)) {
315 errorAutoVariableAssignment(tok->next(), false);
316 }
317 // Invalid pointer deallocation
318 else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings.library.getDeallocFuncInfo(tok)) ||
319 (tok->isCpp() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) {
320 tok = Token::findmatch(tok->next(), "%var%|%str%");
321 if (Token::simpleMatch(tok->astParent(), "."))
322 continue;
323 if (isArrayVar(tok) || tok->tokType() == Token::eString)
324 errorInvalidDeallocation(tok, nullptr);
325 else if (tok->variable() && tok->variable()->isPointer()) {
326 for (const ValueFlow::Value &v : tok->values()) {
327 if (v.isImpossible())
328 continue;
329 if ((v.isTokValue() && (isArrayVar(v.tokvalue) || (v.tokvalue->tokType() == Token::eString))) ||
330 (v.isLocalLifetimeValue() && v.lifetimeKind == ValueFlow::Value::LifetimeKind::Address && !Token::simpleMatch(v.tokvalue, "("))) {
331 errorInvalidDeallocation(tok, &v);
332 break;
333 }
334 }
335 }
336 } else if ((Token::Match(tok, "%name% ( & %var% ) ;") && mSettings.library.getDeallocFuncInfo(tok)) ||
337 (tok->isCpp() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) {
338 tok = Token::findmatch(tok->next(), "%var%");
339 if (isAutoVar(tok))
340 errorInvalidDeallocation(tok, nullptr);

Callers 1

runChecksMethod · 0.80

Calls 15

findLambdaEndTokenFunction · 0.85
isRefPtrArgFunction · 0.85
isAutoVariableRHSFunction · 0.85
isPtrArgFunction · 0.85
hasOverloadedAssignmentFunction · 0.85
isMemberAssignmentFunction · 0.85
isArrayArgFunction · 0.85
isArrayVarFunction · 0.85
isAutoVarFunction · 0.85
nextMethod · 0.80
astOperand2Method · 0.80
linkAtMethod · 0.80

Tested by

no test coverage detected