Fix 10575: Improve check; lifetime, struct member points to local data (#3541)
This commit is contained in:
parent
be14866095
commit
7d7584b456
|
@ -496,13 +496,22 @@ static bool isDanglingSubFunction(const Token* tokvalue, const Token* tok)
|
||||||
return exprDependsOnThis(parent);
|
return exprDependsOnThis(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Variable* getParentVar(const Token* tok)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return nullptr;
|
||||||
|
if (Token::simpleMatch(tok, "."))
|
||||||
|
return getParentVar(tok->astOperand1());
|
||||||
|
return tok->variable();
|
||||||
|
}
|
||||||
|
|
||||||
static bool isAssignedToNonLocal(const Token* tok)
|
static bool isAssignedToNonLocal(const Token* tok)
|
||||||
{
|
{
|
||||||
if (!Token::simpleMatch(tok->astParent(), "="))
|
if (!Token::simpleMatch(tok->astParent(), "="))
|
||||||
return false;
|
return false;
|
||||||
if (!Token::Match(tok->astParent()->astOperand1(), "%var%"))
|
if (!astIsRHS(tok))
|
||||||
return false;
|
return false;
|
||||||
const Variable* var = tok->astParent()->astOperand1()->variable();
|
const Variable* var = getParentVar(tok->astParent()->astOperand1());
|
||||||
if (!var)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
return !var->isLocal() || var->isStatic();
|
return !var->isLocal() || var->isStatic();
|
||||||
|
@ -597,8 +606,8 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
||||||
const Variable * var = nullptr;
|
const Variable * var = nullptr;
|
||||||
const Token * tok2 = tok;
|
const Token * tok2 = tok;
|
||||||
if (Token::simpleMatch(tok->astParent(), "=")) {
|
if (Token::simpleMatch(tok->astParent(), "=")) {
|
||||||
if (tok->astParent()->astOperand2() == tok) {
|
if (astIsRHS(tok)) {
|
||||||
var = getLHSVariable(tok->astParent());
|
var = getParentVar(tok->astParent()->astOperand1());
|
||||||
tok2 = tok->astParent()->astOperand1();
|
tok2 = tok->astParent()->astOperand1();
|
||||||
}
|
}
|
||||||
} else if (tok->variable() && tok->variable()->declarationId() == tok->varId()) {
|
} else if (tok->variable() && tok->variable()->declarationId() == tok->varId()) {
|
||||||
|
|
|
@ -2833,6 +2833,25 @@ private:
|
||||||
" auto getMore() -> int & { return get(); }\n"
|
" auto getMore() -> int & { return get(); }\n"
|
||||||
"};\n");
|
"};\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// #10575
|
||||||
|
check("struct Data {\n"
|
||||||
|
" int x=0;\n"
|
||||||
|
" int y=0;\n"
|
||||||
|
"};\n"
|
||||||
|
"struct MoreData {\n"
|
||||||
|
" Data *data1;\n"
|
||||||
|
"};\n"
|
||||||
|
"struct Fred {\n"
|
||||||
|
" Fred() {\n"
|
||||||
|
" Data data;\n"
|
||||||
|
" mMoreData.data1 = &data;\n"
|
||||||
|
" }\n"
|
||||||
|
" MoreData mMoreData;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:11] -> [test.cpp:10] -> [test.cpp:11]: (error) Non-local variable 'mMoreData.data1' will use pointer to local variable 'data'.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void danglingLifetimeFunction() {
|
void danglingLifetimeFunction() {
|
||||||
|
|
Loading…
Reference in New Issue