parent
831aec5c03
commit
4b9f3c68fb
|
@ -3265,6 +3265,18 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings
|
||||||
return ExprUsage::Inconclusive;
|
return ExprUsage::Inconclusive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLeafDot(const Token* tok)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return false;
|
||||||
|
const Token * parent = tok->astParent();
|
||||||
|
if (!Token::simpleMatch(parent, "."))
|
||||||
|
return false;
|
||||||
|
if (parent->astOperand2() == tok && !Token::simpleMatch(parent->astParent(), "."))
|
||||||
|
return true;
|
||||||
|
return isLeafDot(parent);
|
||||||
|
}
|
||||||
|
|
||||||
ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp)
|
ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp)
|
||||||
{
|
{
|
||||||
const Token* parent = tok->astParent();
|
const Token* parent = tok->astParent();
|
||||||
|
@ -3285,6 +3297,13 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings,
|
||||||
!parent->isUnaryOp("&") &&
|
!parent->isUnaryOp("&") &&
|
||||||
!(astIsRHS(tok) && isLikelyStreamRead(cpp, parent)))
|
!(astIsRHS(tok) && isLikelyStreamRead(cpp, parent)))
|
||||||
return ExprUsage::Used;
|
return ExprUsage::Used;
|
||||||
|
if (isLeafDot(tok)) {
|
||||||
|
const Token* op = parent->astParent();
|
||||||
|
while (Token::simpleMatch(op, "."))
|
||||||
|
op = op->astParent();
|
||||||
|
if (Token::Match(op, "%assign%|++|--") && op->str() != "=")
|
||||||
|
return ExprUsage::Used;
|
||||||
|
}
|
||||||
if (Token::simpleMatch(parent, "=") && astIsRHS(tok)) {
|
if (Token::simpleMatch(parent, "=") && astIsRHS(tok)) {
|
||||||
const Token* const lhs = parent->astOperand1();
|
const Token* const lhs = parent->astOperand1();
|
||||||
if (lhs && lhs->variable() && lhs->variable()->isReference() && lhs == lhs->variable()->nameToken())
|
if (lhs && lhs->variable() && lhs->variable()->isReference() && lhs == lhs->variable()->nameToken())
|
||||||
|
|
|
@ -418,6 +418,8 @@ bool isCPPCast(const Token* tok);
|
||||||
|
|
||||||
bool isConstVarExpression(const Token* tok, std::function<bool(const Token*)> skipPredicate = nullptr);
|
bool isConstVarExpression(const Token* tok, std::function<bool(const Token*)> skipPredicate = nullptr);
|
||||||
|
|
||||||
|
bool isLeafDot(const Token* tok);
|
||||||
|
|
||||||
enum class ExprUsage { None, NotUsed, PassedByReference, Used, Inconclusive };
|
enum class ExprUsage { None, NotUsed, PassedByReference, Used, Inconclusive };
|
||||||
|
|
||||||
ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp);
|
ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp);
|
||||||
|
|
|
@ -1596,18 +1596,6 @@ void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string
|
||||||
"$symbol:" + membername + "\nUninitialized struct member: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal);
|
"$symbol:" + membername + "\nUninitialized struct member: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isLeafDot(const Token* tok)
|
|
||||||
{
|
|
||||||
if (!tok)
|
|
||||||
return false;
|
|
||||||
const Token * parent = tok->astParent();
|
|
||||||
if (!Token::simpleMatch(parent, "."))
|
|
||||||
return false;
|
|
||||||
if (parent->astOperand2() == tok && !Token::simpleMatch(parent->astParent(), "."))
|
|
||||||
return true;
|
|
||||||
return isLeafDot(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckUninitVar::valueFlowUninit()
|
void CheckUninitVar::valueFlowUninit()
|
||||||
{
|
{
|
||||||
logChecker("CheckUninitVar::valueFlowUninit");
|
logChecker("CheckUninitVar::valueFlowUninit");
|
||||||
|
|
|
@ -7215,6 +7215,42 @@ private:
|
||||||
" foo(&my_st);\n"
|
" foo(&my_st);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
valueFlowUninit("struct S {\n" // #12188
|
||||||
|
" int i;\n"
|
||||||
|
" struct T { int j; } t;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" ++s.i;\n"
|
||||||
|
"}\n"
|
||||||
|
"void g() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" s.i--;\n"
|
||||||
|
"}\n"
|
||||||
|
"void h() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" s.i &= 3;\n"
|
||||||
|
"}\n"
|
||||||
|
"void k() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" if (++s.i < 3) {}\n"
|
||||||
|
"}\n"
|
||||||
|
"void m() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" ++s.t.j;\n"
|
||||||
|
"}\n"
|
||||||
|
"void n() {\n"
|
||||||
|
" S s;\n"
|
||||||
|
" if (s.t.j-- < 3) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: s.i\n"
|
||||||
|
"[test.cpp:11]: (error) Uninitialized variable: s.i\n"
|
||||||
|
"[test.cpp:15]: (error) Uninitialized variable: s.i\n"
|
||||||
|
"[test.cpp:19]: (error) Uninitialized variable: s.i\n"
|
||||||
|
"[test.cpp:23]: (error) Uninitialized variable: s.t.j\n"
|
||||||
|
"[test.cpp:27]: (error) Uninitialized variable: s.t.j\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_memberfunction() {
|
void uninitvar_memberfunction() {
|
||||||
|
|
Loading…
Reference in New Issue