Skip to content

Commit 2eb4e94

Browse files
Fix #14639 FN danglingLifetime (address stored in non-local container) (danmar#8406)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent c0793bb commit 2eb4e94

2 files changed

Lines changed: 31 additions & 3 deletions

File tree

lib/checkautovariables.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,8 @@ bool CheckAutoVariables::checkAutoVariableAssignment(const Token *expr, bool inc
394394

395395
void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive)
396396
{
397+
diag(tok);
398+
397399
if (!inconclusive) {
398400
reportError(tok, Severity::error, "autoVariables",
399401
"Address of local auto-variable assigned to a function parameter.\n"
@@ -674,14 +676,16 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
674676
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop());
675677
if (!nextTok)
676678
nextTok = tok->next();
677-
if (var && (!var->isLocal() || var->isStatic()) && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
679+
if (var && (!var->isLocal() || var->isStatic()) && (!var->isArgument() || (var->isReference() && isInScope(val.tokvalue, var->scope()))) &&
680+
!(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&
678681
!isVariableChanged(nextTok,
679682
tok->scope()->bodyEnd,
680683
var->valueType() ? var->valueType()->pointer : 0,
681684
var->declarationId(),
682685
var->isGlobal(),
683686
*mSettings)) {
684-
errorDanglngLifetime(tok2, &val, var->isLocal());
687+
if (!diag(tok2))
688+
errorDanglngLifetime(tok2, &val, var->isLocal());
685689
break;
686690
}
687691
}
@@ -823,8 +827,8 @@ void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro
823827
{
824828
CheckAutoVariables checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger);
825829
checkAutoVariables.assignFunctionArg();
826-
checkAutoVariables.checkVarLifetime();
827830
checkAutoVariables.autoVariables();
831+
checkAutoVariables.checkVarLifetime();
828832
}
829833

830834
void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const

test/testautovariables.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,6 +2937,30 @@ class TestAutoVariables : public TestFixture {
29372937
" return it;\n"
29382938
"}\n");
29392939
ASSERT_EQUALS("[test.cpp:3:44] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str());
2940+
2941+
check("void f(std::vector<int*>& m) {\n"
2942+
" int x;\n"
2943+
" m.push_back(&x);\n"
2944+
"}\n");
2945+
ASSERT_EQUALS("[test.cpp:3:17] -> [test.cpp:3:17] -> [test.cpp:2:9] -> [test.cpp:3:5]: (error) Non-local variable 'm' will use object that points to local variable 'x'. [danglingLifetime]\n", errout_str());
2946+
2947+
check("struct P {\n"
2948+
" int h() const;\n"
2949+
" int x;\n"
2950+
" int& r;\n"
2951+
"};\n"
2952+
"int f(const P& p) {\n"
2953+
" return p.h();\n"
2954+
"}\n"
2955+
"struct C {\n"
2956+
" void g() {\n"
2957+
" int i = 1;\n"
2958+
" P q(m, i);\n"
2959+
" f(q);\n"
2960+
" }\n"
2961+
" int m;\n"
2962+
"}\n");
2963+
ASSERT_EQUALS("", errout_str());
29402964
}
29412965

29422966
void danglingLifetimeContainerView()

0 commit comments

Comments
 (0)