diff --git a/src/checkclass.cpp b/src/checkclass.cpp index c7a71dd99..7c5fdca7a 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -79,7 +79,7 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1) // If next token contains a ":".. it is not part of a variable declaration if (next->str().find(":") != std::string::npos) { - + } // Is it a variable declaration? @@ -91,28 +91,12 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1) varname = next->strAt(1); } - // Is it a variable declaration? - else if (Token::Match(next, "%type% %type% %var% ;")) - { - const Token *next2 = next->next(); - if (next2->isStandardType()) - varname = next2->strAt(1); - else if (Token::findmatch(_tokenizer->tokens(), ("enum " + next2->str()).c_str())) - varname = next2->strAt(1); - } - // Pointer? else if (Token::Match(next, "%type% * %var% ;")) { varname = next->strAt(2); } - // Pointer? - else if (!b && Token::Match(next, "%type% %type% * %var% ;")) - { - varname = next->strAt(3); - } - // If the varname was set in one of the two if-block above, create a entry for this variable.. if (varname) { diff --git a/src/tokenize.cpp b/src/tokenize.cpp index 003e7a3b4..71fa6872f 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -482,6 +482,22 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[]) tok->deleteNext(); } } + + // Remove "mutable" + while (Token::simpleMatch(_tokens, "mutable")) + { + Token *tok = _tokens; + _tokens = _tokens->next(); + delete tok; + } + for (Token *tok = _tokens; tok; tok = tok->next()) + { + while (Token::simpleMatch(tok->next(), "mutable")) + { + tok->deleteNext(); + } + } + } //--------------------------------------------------------------------------- diff --git a/test/testclass.cpp b/test/testclass.cpp index 28474faf1..21cddc264 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -51,6 +51,9 @@ private: TEST_CASE(uninitVarHeader1); // Class is defined in header TEST_CASE(uninitVarHeader2); // Class is defined in header TEST_CASE(uninitVarHeader3); // Class is defined in header + + TEST_CASE(noConstructor1); + TEST_CASE(noConstructor2); } // Check that base classes have virtual destructors @@ -296,6 +299,61 @@ private: } + + + + void checkNoConstructor(const char code[]) + { + // Tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.simplifyTokenList(); + + // Clear the error log + errout.str(""); + + // Check.. + Settings settings; + settings._checkCodingStyle = true; + CheckClass checkClass(&tokenizer, settings, this); + checkClass.constructors(); + } + + void noConstructor1() + { + // There are nonstatic member variables - constructor is needed + checkNoConstructor("class Fred\n" + "{\n" + " int i;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) The class 'Fred' has no constructor\n", errout.str()); + } + + void noConstructor2() + { + checkNoConstructor("class Fred\n" + "{\n" + "public:\n" + " static void foobar();\n" + "};\n" + "\n" + "void Fred::foobar()\n" + "{ }\n"); + ASSERT_EQUALS("", errout.str()); + } + + void noConstructor3() + { + checkNoConstructor("class Fred\n" + "{\n" + "public:\n" + " static int foobar;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + + }; REGISTER_TEST(TestClass)