From 9dd3bce98bdbb8908c5b601965097f97baa45f12 Mon Sep 17 00:00:00 2001 From: Frank Zingsheim Date: Thu, 16 Oct 2014 09:11:09 +0200 Subject: [PATCH] Fixed #6214: non-static member initializer causes false positive --- lib/symboldatabase.cpp | 16 ++++++++++++++-- lib/symboldatabase.h | 9 +++++++++ test/testconstructors.cpp | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 3eecd351a..62ce21beb 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1136,6 +1136,17 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const return false; } +const Token * Variable::declEndToken() const +{ + Token const * declEnd = typeStartToken(); + while (declEnd && !Token::Match(declEnd, "[;,)={]")) { + if (declEnd->link() && Token::Match(declEnd,"(|[")) + declEnd = declEnd->link(); + declEnd = declEnd->next(); + } + return declEnd; +} + void Variable::evaluate() { const Token* tok = _start; @@ -1204,8 +1215,9 @@ void Variable::evaluate() // type var = x or // type var = {x} // type var = x; gets simplified to: type var ; var = x ; - if ((Token::Match(_name, "%var% ; %var% = ") && _name->strAt(2) == _name->str()) || - Token::Match(_name, "%var% {")) + Token const * declEnd = declEndToken(); + if ((Token::Match(declEnd, "; %var% = ") && declEnd->strAt(1) == _name->str()) || + Token::Match(declEnd, "=|{")) setFlag(fHasDefault, true); } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 035eeda66..079e809b2 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -215,6 +215,15 @@ public: return _end; } + /** + * Get end token of variable declaration + * E.g. + * int i[2][3] = ... + * end token ^ + * @return variable declaration end token + */ + const Token *declEndToken() const; + /** * Get name string. * @return name string diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 603ec326d..62e546952 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -385,8 +385,24 @@ private: " int x = 0;\n" " int y = f();\n" " int z{0};\n" + " int (*pf[2])(){nullptr, nullptr};\n" + " int a[2][3] = {{1,2,3},{4,5,6}};\n" + " int d, e{3};\n" "};"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) Member variable 'Fred::d' is not initialized in the constructor.\n", errout.str()); + + check("class Fred {\n" + "public:\n" + " Fred() {}\n" + "private:\n" + " int b{1}, c{2};\n" + " int d, e{3};\n" + " int f{4}, g;\n" + "};"); + TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) Member variable 'Fred::d' is not initialized in the constructor.\n" + "[test.cpp:3]: (warning) Member variable 'Fred::g' is not initialized in the constructor.\n", + "[test.cpp:3]: (warning) Member variable 'Fred::d' is not initialized in the constructor.\n", + errout.str()); // fails due to missing varid } void simple12() { // ticket #4620