Skip to content

Commit 74da655

Browse files
Fix #10902 / #13560 FN danglingLifetime (stack address stored in static variable) (danmar#7225)
1 parent 1cce204 commit 74da655

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

lib/checkautovariables.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -645,14 +645,14 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
645645
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop());
646646
if (!nextTok)
647647
nextTok = tok->next();
648-
if (var && !var->isLocal() && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
648+
if (var && (!var->isLocal() || var->isStatic()) && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
649649
!isVariableChanged(nextTok,
650650
tok->scope()->bodyEnd,
651651
var->valueType() ? var->valueType()->pointer : 0,
652652
var->declarationId(),
653653
var->isGlobal(),
654654
*mSettings)) {
655-
errorDanglngLifetime(tok2, &val);
655+
errorDanglngLifetime(tok2, &val, var->isLocal());
656656
break;
657657
}
658658
}
@@ -722,12 +722,13 @@ void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const
722722
inconclusive ? Certainty::inconclusive : Certainty::normal);
723723
}
724724

725-
void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val)
725+
void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic)
726726
{
727727
const bool inconclusive = val ? val->isInconclusive() : false;
728728
ErrorPath errorPath = val ? val->errorPath : ErrorPath();
729729
std::string tokName = tok ? tok->expressionString() : "x";
730-
std::string msg = "Non-local variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath);
730+
std::string msg = isStatic ? "Static" : "Non-local";
731+
msg += " variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath);
731732
errorPath.emplace_back(tok, "");
732733
reportError(errorPath, Severity::error, "danglingLifetime", msg + ".", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
733734
}

lib/checkautovariables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class CPPCHECKLIB CheckAutoVariables : public Check {
7575
void errorAutoVariableAssignment(const Token *tok, bool inconclusive);
7676
void errorReturnDanglingLifetime(const Token *tok, const ValueFlow::Value* val);
7777
void errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val);
78-
void errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val);
78+
void errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic = false);
7979
void errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val, const Token* tempTok);
8080
void errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive);
8181
void errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath);

test/testautovariables.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,6 +3449,25 @@ class TestAutoVariables : public TestFixture {
34493449
" std::vector<int*> v;\n"
34503450
"};\n");
34513451
ASSERT_EQUALS("", errout_str());
3452+
3453+
// #13560
3454+
check("void f() {\n"
3455+
" int a[] = { 1 };\n"
3456+
" static int* p = nullptr;\n"
3457+
" if (!p) {\n"
3458+
" p = &a[0];\n"
3459+
" }\n"
3460+
" *p = 0;\n"
3461+
"}\n");
3462+
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());
3463+
3464+
// #10902
3465+
check("void f() {\n"
3466+
" static int* x;\n"
3467+
" int y;\n"
3468+
" x = &y;\n"
3469+
"}\n");
3470+
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());
34523471
}
34533472

34543473
void danglingLifetimeFunction() {

0 commit comments

Comments
 (0)