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

Method checkMisusedScopedObject

lib/checkother.cpp:2544–2617  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Creating instance of classes which are destroyed immediately ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

2542// Creating instance of classes which are destroyed immediately
2543//---------------------------------------------------------------------------
2544void CheckOtherImpl::checkMisusedScopedObject()
2545{
2546 // Skip this check for .c files
2547 if (mTokenizer->isC())
2548 return;
2549
2550 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedScopedObject"))
2551 return;
2552
2553 logChecker("CheckOther::checkMisusedScopedObject"); // style,c++
2554
2555 auto getConstructorTok = [](const Token* tok, std::string& typeStr) -> const Token* {
2556 if (!Token::Match(tok, "[;{}] %name%") || tok->next()->isKeyword())
2557 return nullptr;
2558 tok = tok->next();
2559 typeStr.clear();
2560 while (Token::Match(tok, "%name% ::")) {
2561 typeStr += tok->str();
2562 typeStr += "::";
2563 tok = tok->tokAt(2);
2564 }
2565 typeStr += tok->str();
2566 const Token* endTok = tok;
2567 if (Token::Match(endTok, "%name% <"))
2568 endTok = endTok->linkAt(1);
2569 if (Token::Match(endTok, "%name%|> (|{") && Token::Match(endTok->linkAt(1), ")|} ;") &&
2570 !Token::simpleMatch(endTok->next()->astParent(), ";")) { // for loop condition
2571 return tok;
2572 }
2573 return nullptr;
2574 };
2575
2576 auto isLibraryConstructor = [&](const Token* tok, const std::string& typeStr) -> bool {
2577 const Library::TypeCheck typeCheck = mSettings.library.getTypeCheck("unusedvar", typeStr);
2578 if (typeCheck == Library::TypeCheck::check || typeCheck == Library::TypeCheck::checkFiniteLifetime)
2579 return true;
2580 return mSettings.library.detectContainerOrIterator(tok);
2581 };
2582
2583 const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
2584 std::string typeStr;
2585 for (const Scope * scope : symbolDatabase->functionScopes) {
2586 for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
2587 const Token* ctorTok = getConstructorTok(tok, typeStr);
2588 if (ctorTok && (((ctorTok->type() || ctorTok->isStandardType() || (ctorTok->function() && ctorTok->function()->isConstructor())) // TODO: The rhs of || should be removed; It is a workaround for a symboldatabase bug
2589 && (!ctorTok->function() || ctorTok->function()->isConstructor()) // // is not a function on this scope or is function in this scope and it's a ctor
2590 && ctorTok->str() != "void") || isLibraryConstructor(tok->next(), typeStr))) {
2591 const Token* parTok = ctorTok->next();
2592 if (Token::simpleMatch(parTok, "<") && parTok->link())
2593 parTok = parTok->link()->next();
2594 if (const Token* arg = parTok->astOperand2()) {
2595 if (!isConstStatement(arg, mSettings.library, false))
2596 continue;
2597 if (parTok->str() == "(") {
2598 if (arg->varId() && !(arg->variable() && arg->variable()->nameToken() != arg))
2599 continue;
2600 const Token* rml = nextAfterAstRightmostLeaf(arg);
2601 if (rml && rml->previous() && rml->previous()->varId())

Callers 1

runChecksMethod · 0.80

Calls 15

isConstStatementFunction · 0.85
isCMethod · 0.80
isPremiumEnabledMethod · 0.80
nextMethod · 0.80
linkAtMethod · 0.80
astParentMethod · 0.80
getTypeCheckMethod · 0.80
typeMethod · 0.80
astOperand2Method · 0.80
variableMethod · 0.80

Tested by

no test coverage detected