From da302b39127ae66c586da096a422f455f86133f0 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sun, 10 May 2015 14:27:15 +0200 Subject: [PATCH] Ticket #6680: Members can be initialized by operator>>. --- lib/checkuninitvar.cpp | 2 ++ test/testuninitvar.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 3b6949128..28597a523 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1886,6 +1886,8 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str return true; else if (Token::Match(tok->tokAt(-2), "[(,=] &")) return true; + else if (Token::Match(tok->tokAt(-2), "%name% >>") && Token::Match(tok->tokAt(3), ";|>>")) // #6680 + return true; else if ((tok->previous() && tok->previous()->isConstOp()) || Token::Match(tok->previous(), "[|=")) ; // member variable usage else if (tok->tokAt(3)->isConstOp()) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index a817a064d..31ab51497 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -70,6 +70,7 @@ private: TEST_CASE(uninitvar9); // ticket #6424 TEST_CASE(uninitvar_unconditionalTry); TEST_CASE(uninitvar_funcptr); // #6404 + TEST_CASE(uninitvar_operator); // #6680 TEST_CASE(syntax_error); // Ticket #5073 @@ -2869,6 +2870,25 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: Factory\n", errout.str()); } + + void uninitvar_operator() { // Ticket #6680 + checkUninitVar2("struct Source { Source& operator>>(int& i) { i = 0; return *this; } };\n" + "struct Sink { int v; };\n" + "Source foo;\n" + "void uninit() {\n" + " Sink s;\n" + " int n = 1 >> s.v;\n" // Not initialized + "};\n" + "void notUninit() {\n" + " Sink s1;\n" + " foo >> s1.v;\n" // Initialized by operator>> + " Sink s2;\n" + " int n;\n" + " foo >> s2.v >> n;\n" // Initialized by operator>> + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized struct member: s.v\n", errout.str()); + } + // Handling of function calls void uninitvar2_func() { // non-pointer variable