diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 91df3b584..eb35c4eb3 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -46,6 +46,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses) // Get variable list.. Var *varlist = NULL; unsigned int indentlevel = 0; + bool priv = true; for (const Token *tok = tok1; tok; tok = tok->next()) { if (!tok->next()) @@ -65,6 +66,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses) if (tok->str() == "__published:") { + priv = false; for (; tok; tok = tok->next()) { if (tok->str() == "{") @@ -87,6 +89,9 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses) // "private:" "public:" "protected:" etc const bool b((*tok->strAt(0) != ':') && strchr(tok->strAt(0), ':') != 0); + if (b) + priv = bool(tok->str() == "private:"); + // Search for start of statement.. if (! Token::Match(tok, "[;{}]") && ! b) continue; @@ -162,8 +167,8 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses) // If the varname was set in one of the two if-block above, create a entry for this variable.. if (varname) { - Var *var = new Var(varname, false, varlist); - varlist = var; + Var *var = new Var(varname, false, priv, varlist); + varlist = var; } } @@ -401,14 +406,21 @@ void CheckClass::constructors() if (! constructor_token) { // If "--style" has been given, give a warning - if (ErrorLogger::noConstructor(*_settings)) + if (_settings->_checkCodingStyle) { - // If the class has member variables there should be an constructor + // Get class variables... Var *varlist = getVarList(tok1, false); - if (varlist) + + // If there is a private variable, there should be a constructor.. + for (const struct Var *var = varlist; var; var = var->next) { - noConstructorError(tok1, classNameToken->str()); + if (var->priv) + { + noConstructorError(tok1, classNameToken->str()); + break; + } } + // Delete the varlist.. while (varlist) { diff --git a/lib/checkclass.h b/lib/checkclass.h index d249d9d36..e8bbec26b 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -86,15 +86,17 @@ private: class Var { public: - Var(const char *name = 0, bool init = false, Var *next = 0) + Var(const char *name = 0, bool init = false, bool priv = false, Var *next = 0) { this->name = name; this->init = init; + this->priv = priv; this->next = next; } const char *name; bool init; + bool priv; Var *next; }; diff --git a/test/testclass.cpp b/test/testclass.cpp index d7333a1b9..a9a5d1e13 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -62,6 +62,8 @@ private: TEST_CASE(noConstructor1); TEST_CASE(noConstructor2); + TEST_CASE(noConstructor3); + TEST_CASE(noConstructor4); TEST_CASE(operatorEq1); TEST_CASE(memsetOnStruct); @@ -703,12 +705,22 @@ private: { checkNoConstructor("class Fred\n" "{\n" - "public:\n" + "private:\n" " static int foobar;\n" "};\n"); ASSERT_EQUALS("", errout.str()); } + void noConstructor4() + { + checkNoConstructor("class Fred\n" + "{\n" + "public:\n" + " int foobar;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + void checkNoMemset(const char code[]) { // Tokenize.. diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index e8effa236..5d36bec94 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -83,7 +83,7 @@ private: { check("class Fred\n" "{\n" - "public:\n" + "private:\n" " int i;\n" "};\n"); ASSERT_EQUALS("[test.cpp:1]: (style) The class 'Fred' has no constructor. Member variables not initialized.\n", errout.str());