Skip to content

Commit

Permalink
Fix #10902 / #13560 FN danglingLifetime (stack address stored in stat…
Browse files Browse the repository at this point in the history
…ic variable) (#7225)
  • Loading branch information
chrchr-github authored Jan 16, 2025
1 parent 1cce204 commit 74da655
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
9 changes: 5 additions & 4 deletions lib/checkautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,14 +645,14 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop());
if (!nextTok)
nextTok = tok->next();
if (var && !var->isLocal() && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
if (var && (!var->isLocal() || var->isStatic()) && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
!isVariableChanged(nextTok,
tok->scope()->bodyEnd,
var->valueType() ? var->valueType()->pointer : 0,
var->declarationId(),
var->isGlobal(),
*mSettings)) {
errorDanglngLifetime(tok2, &val);
errorDanglngLifetime(tok2, &val, var->isLocal());
break;
}
}
Expand Down Expand Up @@ -722,12 +722,13 @@ void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const
inconclusive ? Certainty::inconclusive : Certainty::normal);
}

void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val)
void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic)
{
const bool inconclusive = val ? val->isInconclusive() : false;
ErrorPath errorPath = val ? val->errorPath : ErrorPath();
std::string tokName = tok ? tok->expressionString() : "x";
std::string msg = "Non-local variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath);
std::string msg = isStatic ? "Static" : "Non-local";
msg += " variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "danglingLifetime", msg + ".", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/checkautovariables.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class CPPCHECKLIB CheckAutoVariables : public Check {
void errorAutoVariableAssignment(const Token *tok, bool inconclusive);
void errorReturnDanglingLifetime(const Token *tok, const ValueFlow::Value* val);
void errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val);
void errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val);
void errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic = false);
void errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val, const Token* tempTok);
void errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive);
void errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath);
Expand Down
19 changes: 19 additions & 0 deletions test/testautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3449,6 +3449,25 @@ class TestAutoVariables : public TestFixture {
" std::vector<int*> v;\n"
"};\n");
ASSERT_EQUALS("", errout_str());

// #13560
check("void f() {\n"
" int a[] = { 1 };\n"
" static int* p = nullptr;\n"
" if (!p) {\n"
" p = &a[0];\n"
" }\n"
" *p = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:2] -> [test.cpp:7]: (error) Static variable 'p' will use pointer to local variable 'a'.\n", errout_str());

// #10902
check("void f() {\n"
" static int* x;\n"
" int y;\n"
" x = &y;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Static variable 'x' will use pointer to local variable 'y'.\n", errout_str());
}

void danglingLifetimeFunction() {
Expand Down

0 comments on commit 74da655

Please sign in to comment.