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

Method checkVarLifetimeScope

lib/checkautovariables.cpp:565–706  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

563}
564
565void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const Token * end)
566{
567 const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive);
568 if (!start)
569 return;
570 const Scope * scope = start->scope();
571 if (!scope)
572 return;
573 // If the scope is not set correctly then skip checking it
574 if (scope->bodyStart != start)
575 return;
576 const bool returnRef = Function::returnsReference(scope->function);
577 for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
578 // Return reference from function
579 if (returnRef && Token::simpleMatch(tok->astParent(), "return")) {
580 for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, mSettings, true)) {
581 if (!printInconclusive && lt.inconclusive)
582 continue;
583 const Variable* var = lt.token->variable();
584 if (var && !var->isGlobal() && !var->isStatic() && !var->isReference() && !var->isRValueReference() &&
585 isInScope(var->nameToken(), tok->scope())) {
586 errorReturnReference(tok, lt.errorPath, lt.inconclusive);
587 break;
588 }
589 if (isDeadTemporary(lt.token, nullptr, mSettings.library)) {
590 errorReturnTempReference(tok, lt.errorPath, lt.inconclusive);
591 break;
592 }
593 }
594 // Assign reference to non-local variable
595 } else if (Token::Match(tok->previous(), "&|&& %var% =") && tok->astParent() == tok->next() &&
596 tok->variable() && tok->variable()->nameToken() == tok &&
597 tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() &&
598 !tok->variable()->isArgument()) {
599 ErrorPath errorPath;
600 const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath, mSettings);
601 if (var && isInScope(var->nameToken(), tok->scope())) {
602 errorDanglingReference(tok, var, std::move(errorPath));
603 continue;
604 }
605 // Reference to temporary
606 } else if (tok->variable() && (tok->variable()->isReference() || tok->variable()->isRValueReference())) {
607 for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok), mSettings)) {
608 if (!printInconclusive && lt.inconclusive)
609 continue;
610 const Token * tokvalue = lt.token;
611 if (isDeadTemporary(tokvalue, tok, mSettings.library)) {
612 errorDanglingTempReference(tok, lt.errorPath, lt.inconclusive);
613 break;
614 }
615 }
616 }
617 const bool escape = Token::simpleMatch(tok->astParent(), "throw") ||
618 (Token::simpleMatch(tok->astParent(), "return") && !Function::returnsStandardType(scope->function));
619 std::unordered_set<const Token*> exprs;
620 for (const ValueFlow::Value& val:tok->values()) {
621 if (!val.isLocalLifetimeValue() && !val.isSubFunctionLifetimeValue())
622 continue;

Callers

nothing calls this directly

Calls 15

getLifetimeTokensFunction · 0.85
isInScopeFunction · 0.85
isDeadTemporaryFunction · 0.85
getParentLifetimeFunction · 0.85
isAssignedToNonLocalFunction · 0.85
getPointerDepthFunction · 0.85
isLifetimeBorrowedFunction · 0.85
astIsContainerViewFunction · 0.85
isEscapedReferenceFunction · 0.85
isDeadScopeFunction · 0.85
isDanglingSubFunctionFunction · 0.85
astIsRHSFunction · 0.85

Tested by

no test coverage detected