From 3507b06e0b28e8078b1337d7f06799e68f62698c Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 2 Apr 2010 08:02:47 +0200 Subject: [PATCH] Fixed #1563 (false positive: function can be const (assignment to static)) --- lib/checkclass.cpp | 18 +++++++++++------- lib/checkclass.h | 6 +++++- test/testclass.cpp | 12 ++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 48ea26ee9..03698880a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -100,10 +100,6 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo if (next->str().find(":") != std::string::npos) continue; - // Variable declarations that start with "static" shall be ignored.. - if (next->str() == "static") - continue; - // Borland C++: Ignore properties.. if (next->str() == "__property") continue; @@ -112,6 +108,14 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo if (next->str() == "typedef") continue; + // Is it a static variable? + bool isStatic = false; + if (next->str() == "static") + { + isStatic = true; + next = next->next(); + } + // Is it a mutable variable? bool isMutable = false; if (next->str() == "mutable") @@ -185,7 +189,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo // If the varname was set in one of the two if-block above, create a entry for this variable.. if (!varname.empty() && varname != "operator") { - Var *var = new Var(varname, false, priv, isMutable, varlist); + Var *var = new Var(varname, false, priv, isMutable, isStatic, varlist); varlist = var; } } @@ -507,7 +511,7 @@ void CheckClass::constructors() // If there is a private variable, there should be a constructor.. for (const Var *var = varlist; var; var = var->next) { - if (var->priv) + if (var->priv && !var->isStatic) { noConstructorError(tok1, classNameToken->str(), isStruct); break; @@ -586,7 +590,7 @@ void CheckClass::checkConstructors(const Token *tok1, const std::string &funcnam if (classNameUsed) operatorEqVarError(constructor_token, className, var->name); } - else + else if (!var->isStatic) uninitVarError(constructor_token, className, var->name, hasPrivateConstructor); } diff --git a/lib/checkclass.h b/lib/checkclass.h index a9173c2fd..aeb93e936 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -113,11 +113,12 @@ private: class Var { public: - Var(const std::string &name_, bool init_ = false, bool priv_ = false, bool mutable_ = false, Var *next_ = 0) + Var(const std::string &name_, bool init_ = false, bool priv_ = false, bool mutable_ = false, bool static_ = false, Var *next_ = 0) : name(name_), init(init_), priv(priv_), isMutable(mutable_), + isStatic(static_), next(next_) { } @@ -134,6 +135,9 @@ private: /** @brief is this variable mutable? */ bool isMutable; + /** @brief is this variable static? */ + bool isStatic; + /** @brief next Var item */ Var *next; }; diff --git a/test/testclass.cpp b/test/testclass.cpp index 4fb29ddb7..ea1abdeaa 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -110,6 +110,7 @@ private: TEST_CASE(const15); TEST_CASE(const16); // ticket #1551 TEST_CASE(const17); // ticket #1552 + TEST_CASE(const18); // ticket #1563 TEST_CASE(constoperator); // operator< can often be const TEST_CASE(constincdec); // increment/decrement => non-const TEST_CASE(constReturnReference); @@ -2817,6 +2818,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void const18() + { + // ticket #1563 + checkConst("class Fred {\n" + "static int x;\n" + "public:\n" + " void set(int i) { x = i; }\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + // increment/decrement => not const void constincdec() {