From e35c46bcb9c63f2a8d909cf97be9d71a385b1d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 18 May 2021 21:03:43 +0200 Subject: [PATCH] Uninitialized variables; Fixed false positive for overloaded & 'ar & a & b & c' --- lib/checkuninitvar.cpp | 15 +++++++++++++-- test/testuninitvar.cpp | 7 +++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 44c6f70af..bf8402a73 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1166,8 +1166,19 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, if (astIsRhs(derefValue) && isLikelyStreamRead(mTokenizer->isCPP(), derefValue->astParent())) return nullptr; - if (mTokenizer->isCPP() && Token::simpleMatch(valueExpr->astParent(), "&") && !valueExpr->astParent()->astParent() && astIsRhs(valueExpr) && Token::Match(valueExpr->astSibling(), "%type%")) - return nullptr; + // Assignment with overloaded & + if (mTokenizer->isCPP() && Token::simpleMatch(valueExpr->astParent(), "&") && astIsRhs(valueExpr)) { + const Token *parent = valueExpr->astParent(); + while (Token::simpleMatch(parent, "&") && parent->isBinaryOp()) + parent = parent->astParent(); + if (!parent) { + const Token *lhs = valueExpr->astParent(); + while (Token::simpleMatch(lhs, "&") && lhs->isBinaryOp()) + lhs = lhs->astOperand1(); + if (lhs && lhs->isName() && (!lhs->valueType() || lhs->valueType()->type <= ValueType::Type::CONTAINER)) + return nullptr; // <- possible assignment + } + } return derefValue ? derefValue : valueExpr; } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index dfa687a2b..402f926b6 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -534,12 +534,19 @@ private: " a & x;\n" "}"); ASSERT_EQUALS("", errout.str()); + checkUninitVar("void f(int a) {\n" " int x;\n" " a & x;\n" "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str()); + checkUninitVar("void f() {\n" + " int a,b,c;\n" + " ar & a & b & c;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + checkUninitVar("void a() {\n" // asm " int x;\n" " asm();\n"