diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 0cab834a9..b29ffa302 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1275,6 +1275,15 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const return true; } + if (_tokenizer->isCPP() && Token::Match(vartok->next(), "<<|>>")) { + // Is variable a known POD type then this is a variable usage, + // otherwise we assume it's not. + const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(vartok->varId()); + if (var && var->typeStartToken()->isStandardType()) + return true; + return false; + } + if (Token::Match(vartok->next(), "++|--|%op%")) return true; diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 3e397ee38..4818d29be 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -54,6 +54,7 @@ private: TEST_CASE(uninitvar2); TEST_CASE(uninitvar3); // #3844 TEST_CASE(uninitvar4); // #3869 (reference) + TEST_CASE(uninitvar5); // #3861 } void checkUninitVar(const char code[]) { @@ -2161,6 +2162,23 @@ private: "}"); ASSERT_EQUALS("", errout.str()); } + + // #3861 + void uninitvar5() { + // ensure there is no false positive + checkUninitVar2("void f() {\n" + " x c;\n" + " c << 2345;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + // ensure there is no false negative + checkUninitVar2("void f() {\n" + " char c;\n" + " char a = c << 2;\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: c\n", errout.str()); + } }; REGISTER_TEST(TestUninitVar)