Fixed #1211 (add struct support for constructor checks)

This commit is contained in:
Robert Reif 2010-01-02 17:29:55 +01:00 committed by Daniel Marjamäki
parent 2e62a3f4c7
commit bcafb30d0d
6 changed files with 384 additions and 34 deletions

View File

@ -41,12 +41,12 @@ CheckClass instance;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses) CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, bool isStruct)
{ {
// Get variable list.. // Get variable list..
Var *varlist = NULL; Var *varlist = NULL;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
bool priv = true; bool priv = !isStruct;
for (const Token *tok = tok1; tok; tok = tok->next()) for (const Token *tok = tok1; tok; tok = tok->next())
{ {
if (!tok->next()) if (!tok->next())
@ -189,7 +189,7 @@ void CheckClass::initVar(Var *varlist, const char varname[])
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack) void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack, bool isStruct)
{ {
bool Assign = false; bool Assign = false;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
@ -285,10 +285,10 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
{ {
callstack.push_back(ftok->str()); callstack.push_back(ftok->str());
int i = 0; int i = 0;
const Token *ftok2 = Tokenizer::findClassFunction(tok1, classname, ftok->strAt(0), i); const Token *ftok2 = Tokenizer::findClassFunction(tok1, classname, ftok->strAt(0), i, isStruct);
if (ftok2) if (ftok2)
{ {
initializeVarList(tok1, ftok2, varlist, classname, callstack); initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct);
} }
else // there is a called member function, but it is not defined where we can find it, so we assume it initializes everything else // there is a called member function, but it is not defined where we can find it, so we assume it initializes everything
{ {
@ -340,22 +340,22 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
void CheckClass::constructors() void CheckClass::constructors()
{ {
const char pattern_class[] = "class %var% [{:]"; const char pattern_class[] = "class|struct %var% [{:]";
// Locate class // Locate class
const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class); const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class);
while (tok1) while (tok1)
{ {
const char *className[2]; const char *className;
className[0] = tok1->strAt(1); className = tok1->strAt(1);
className[1] = 0;
const Token *classNameToken = tok1->tokAt(1); const Token *classNameToken = tok1->tokAt(1);
bool isStruct = tok1->str() == "struct";
/** @todo handling of private constructors should be improved */ /** @todo handling of private constructors should be improved */
bool hasPrivateConstructor = false; bool hasPrivateConstructor = false;
{ {
int indentlevel = 0; int indentlevel = 0;
bool isPrivate = true; bool isPrivate = !isStruct;
for (const Token *tok = tok1; tok; tok = tok->next()) for (const Token *tok = tok1; tok; tok = tok->next())
{ {
// Indentation // Indentation
@ -409,14 +409,14 @@ void CheckClass::constructors()
if (_settings->_checkCodingStyle) if (_settings->_checkCodingStyle)
{ {
// Get class variables... // Get class variables...
Var *varlist = getVarList(tok1, false); Var *varlist = getVarList(tok1, false, isStruct);
// If there is a private variable, there should be a constructor.. // If there is a private variable, there should be a constructor..
for (const Var *var = varlist; var; var = var->next) for (const Var *var = varlist; var; var = var->next)
{ {
if (var->priv) if (var->priv)
{ {
noConstructorError(tok1, classNameToken->str()); noConstructorError(tok1, classNameToken->str(), isStruct);
break; break;
} }
} }
@ -435,27 +435,27 @@ void CheckClass::constructors()
} }
// Check constructors // Check constructors
checkConstructors(tok1, className[0], hasPrivateConstructor); checkConstructors(tok1, className, hasPrivateConstructor, isStruct);
// Check assignment operators // Check assignment operators
checkConstructors(tok1, "operator =", hasPrivateConstructor); checkConstructors(tok1, "operator =", hasPrivateConstructor, isStruct);
tok1 = Token::findmatch(tok1->next(), pattern_class); tok1 = Token::findmatch(tok1->next(), pattern_class);
} }
} }
void CheckClass::checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor) void CheckClass::checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor, bool isStruct)
{ {
const char * const className = tok1->strAt(1); const char * const className = tok1->strAt(1);
// Check that all member variables are initialized.. // Check that all member variables are initialized..
bool withClasses = bool(_settings->_showAll && std::string(funcname) == "operator ="); bool withClasses = bool(_settings->_showAll && std::string(funcname) == "operator =");
Var *varlist = getVarList(tok1, withClasses); Var *varlist = getVarList(tok1, withClasses, isStruct);
int indentlevel = 0; int indentlevel = 0;
const Token *constructor_token = Tokenizer::findClassFunction(tok1, className, funcname, indentlevel); const Token *constructor_token = Tokenizer::findClassFunction(tok1, className, funcname, indentlevel, isStruct);
std::list<std::string> callstack; std::list<std::string> callstack;
initializeVarList(tok1, constructor_token, varlist, className, callstack); initializeVarList(tok1, constructor_token, varlist, className, callstack, isStruct);
while (constructor_token) while (constructor_token)
{ {
// Check if any variables are uninitialized // Check if any variables are uninitialized
@ -500,9 +500,9 @@ void CheckClass::checkConstructors(const Token *tok1, const char funcname[], boo
for (Var *var = varlist; var; var = var->next) for (Var *var = varlist; var; var = var->next)
var->init = false; var->init = false;
constructor_token = Tokenizer::findClassFunction(constructor_token->next(), className, funcname, indentlevel); constructor_token = Tokenizer::findClassFunction(constructor_token->next(), className, funcname, indentlevel, isStruct);
callstack.clear(); callstack.clear();
initializeVarList(tok1, constructor_token, varlist, className, callstack); initializeVarList(tok1, constructor_token, varlist, className, callstack, isStruct);
} }
// Delete the varlist.. // Delete the varlist..
@ -522,7 +522,7 @@ void CheckClass::checkConstructors(const Token *tok1, const char funcname[], boo
void CheckClass::privateFunctions() void CheckClass::privateFunctions()
{ {
// Locate some class // Locate some class
for (const Token *tok1 = Token::findmatch(_tokenizer->tokens(), "class %var% {"); tok1; tok1 = Token::findmatch(tok1->next(), "class %var% {")) for (const Token *tok1 = Token::findmatch(_tokenizer->tokens(), "class|struct %var% {"); tok1; tok1 = Token::findmatch(tok1->next(), "class|struct %var% {"))
{ {
/** @todo check that the whole class implementation is seen */ /** @todo check that the whole class implementation is seen */
// until the todo above is fixed we only check classes that are // until the todo above is fixed we only check classes that are
@ -535,7 +535,8 @@ void CheckClass::privateFunctions()
// Get private functions.. // Get private functions..
std::list<const Token *> FuncList; std::list<const Token *> FuncList;
FuncList.clear(); FuncList.clear();
bool priv = false; bool isStruct = tok1->str() == "struct";
bool priv = !isStruct;
unsigned int indent_level = 0; unsigned int indent_level = 0;
for (const Token *tok = tok1; tok; tok = tok->next()) for (const Token *tok = tok1; tok; tok = tok->next())
{ {
@ -1214,9 +1215,9 @@ void CheckClass::thisSubtraction()
} }
} }
void CheckClass::noConstructorError(const Token *tok, const std::string &classname) void CheckClass::noConstructorError(const Token *tok, const std::string &classname, bool isStruct)
{ {
reportError(tok, Severity::style, "noConstructor", "The class '" + classname + "' has no constructor. Member variables not initialized."); reportError(tok, Severity::style, "noConstructor", "The " + std::string(isStruct ? "struct" : "class") + " '" + classname + "' has no constructor. Member variables not initialized.");
} }
void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool hasPrivateConstructor) void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool hasPrivateConstructor)

View File

@ -110,15 +110,15 @@ private:
Var *next; Var *next;
}; };
void initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack); void initializeVarList(const Token *tok1, const Token *ftok, Var *varlist, const char classname[], std::list<std::string> &callstack, bool isStruct);
void initVar(Var *varlist, const char varname[]); void initVar(Var *varlist, const char varname[]);
Var *getVarList(const Token *tok1, bool withClasses); Var *getVarList(const Token *tok1, bool withClasses, bool isStruct);
// Check constructors for a specified class // Check constructors for a specified class
void checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor); void checkConstructors(const Token *tok1, const char funcname[], bool hasPrivateConstructor, bool isStruct);
// Reporting errors.. // Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname); void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);
void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool hasPrivateConstructor); void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool hasPrivateConstructor);
void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname); void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname);
void unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname); void unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname);
@ -132,7 +132,7 @@ private:
void getErrorMessages() void getErrorMessages()
{ {
noConstructorError(0, "classname"); noConstructorError(0, "classname", false);
uninitVarError(0, "classname", "varname", false); uninitVarError(0, "classname", "varname", false);
operatorEqVarError(0, "classname", ""); operatorEqVarError(0, "classname", "");
unusedPrivateFunctionError(0, "classname", "funcname"); unusedPrivateFunctionError(0, "classname", "funcname");

View File

@ -4548,12 +4548,12 @@ std::string Tokenizer::file(const Token *tok) const
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
const Token * Tokenizer::findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel) const Token * Tokenizer::findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel, bool isStruct)
{ {
if (indentlevel < 0 || tok == NULL) if (indentlevel < 0 || tok == NULL)
return NULL; return NULL;
const std::string classPattern(std::string("class ") + classname + " :|{"); const std::string classPattern(std::string(isStruct ? "struct " : "class ") + classname + " :|{");
const std::string internalPattern(std::string("!!~ ") + funcname + " ("); const std::string internalPattern(std::string("!!~ ") + funcname + " (");
const std::string externalPattern(std::string(classname) + " :: " + funcname + " ("); const std::string externalPattern(std::string(classname) + " :: " + funcname + " (");

View File

@ -106,14 +106,15 @@ public:
std::string file(const Token *tok) const; std::string file(const Token *tok) const;
/** /**
* Find a class member function * Find a class or struct member function
* @param tok where to begin the search * @param tok where to begin the search
* @param classname name of class * @param classname name of class
* @param funcname name of function ("~ Fred" => destructor for fred, "%var%" => any function) * @param funcname name of function ("~ Fred" => destructor for fred, "%var%" => any function)
* @param indentlevel Just an integer that you initialize to 0 before the first call. * @param indentlevel Just an integer that you initialize to 0 before the first call.
* @param is it a struct
* @return First matching token or NULL. * @return First matching token or NULL.
*/ */
static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel); static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentleveal, bool isStruct = false);
/** /**
* get error messages * get error messages

View File

@ -81,17 +81,53 @@ private:
void simple1() void simple1()
{ {
check("class Fred\n"
"{\n"
"public:\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
"private:\n" "private:\n"
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:1]: (style) The class 'Fred' has no constructor. Member variables not initialized.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (style) The class 'Fred' has no constructor. Member variables not initialized.\n", errout.str());
check("struct Fred\n"
"{\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
"private:\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("[test.cpp:1]: (style) The struct 'Fred' has no constructor. Member variables not initialized.\n", errout.str());
} }
void simple2() void simple2()
{ {
check("class Fred\n"
"{\n"
"public:\n"
" Fred() : i(0) { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("class Fred\n"
"{\n"
"public:\n"
" Fred() { i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
"public:\n" "public:\n"
@ -99,11 +135,52 @@ private:
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
check("struct Fred\n"
"{\n"
" Fred() : i(0) { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred() { i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred() { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
} }
void simple3() void simple3()
{ {
check("class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred() :i(0)\n"
"{ }\n");
ASSERT_EQUALS("", errout.str());
check("class Fred\n"
"{\n"
"public:\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ i = 0; }\n");
ASSERT_EQUALS("", errout.str());
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
"public:\n" "public:\n"
@ -113,6 +190,33 @@ private:
"Fred::Fred()\n" "Fred::Fred()\n"
"{ }\n"); "{ }\n");
ASSERT_EQUALS("[test.cpp:7]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
check("struct Fred\n"
"{\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred() :i(0)\n"
"{ }\n");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ i = 0; }\n");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred();\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n");
ASSERT_EQUALS("[test.cpp:6]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
} }
@ -132,6 +236,20 @@ private:
" i = _i;\n" " i = _i;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
check("struct Fred\n"
"{\n"
" Fred();\n"
" Fred(int _i);\n"
" int i;\n"
"};\n"
"Fred::Fred()\n"
"{ }\n"
"Fred::Fred(int _i)\n"
"{\n"
" i = _i;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
} }
@ -145,6 +263,14 @@ private:
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred()\n"
" { this->i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void initvar_if() void initvar_if()
@ -162,6 +288,20 @@ private:
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
"public:\n"
" Fred()\n"
" {\n"
" if (true)\n"
" i = 0;\n"
" else\n"
" i = 1;\n"
" }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void initvar_operator_eq1() void initvar_operator_eq1()
@ -204,6 +344,40 @@ private:
"int main() {}\n"); "int main() {}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" int i;\n"
"\n"
" Fred()\n"
" { i = 0; }\n"
"\n"
" Fred(const Fred &fred)\n"
" { *this = fred; }\n"
"\n"
" const Fred & operator=(const Fred &fred)\n"
" { i = fred.i; return *this; }\n"
"};\n");
ASSERT_EQUALS("", errout.str());
check("struct A\n"
"{\n"
" A() : i(0), j(0) {}\n"
"\n"
" A &operator=(const int &value)\n"
" {\n"
" i = value;\n"
" return (*this);\n"
" }\n"
"\n"
" int i;\n"
" int j;\n"
"};\n"
"\n"
"int main() {}\n");
ASSERT_EQUALS("", errout.str());
} }
@ -217,6 +391,14 @@ private:
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:5]: (possible style) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (possible style) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='\n", errout.str());
check("struct Fred\n"
"{\n"
" Fred() { i = 0; }\n"
" void operator=(const Fred &fred) { }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("[test.cpp:4]: (possible style) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='\n", errout.str());
} }
void initvar_operator_eq3() void initvar_operator_eq3()
@ -231,6 +413,16 @@ private:
" int i;\n" " int i;\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" Fred() { Init(); }\n"
" void operator=(const Fred &fred) { Init(); }\n"
"private:\n"
" void Init() { i = 0; }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void initvar_same_classname() void initvar_same_classname()
@ -256,6 +448,46 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void func1()\n"
"{\n"
" struct Fred\n"
" {\n"
" int a;\n"
" Fred() { a = 0; }\n"
" };\n"
"}\n"
"\n"
"void func2()\n"
"{\n"
" class Fred\n"
" {\n"
" int b;\n"
" Fred() { b = 0; }\n"
" };\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void func1()\n"
"{\n"
" struct Fred\n"
" {\n"
" int a;\n"
" Fred() { a = 0; }\n"
" };\n"
"}\n"
"\n"
"void func2()\n"
"{\n"
" struct Fred\n"
" {\n"
" int b;\n"
" Fred() { b = 0; }\n"
" };\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void initvar_chained_assign() void initvar_chained_assign()
@ -276,6 +508,21 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct c\n"
"{\n"
" c();\n"
"\n"
" int m_iMyInt1;\n"
" int m_iMyInt2;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_iMyInt1 = m_iMyInt2 = 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
@ -310,11 +557,61 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct c\n"
"{\n"
" c();\n"
" c(bool b);"
"\n"
" void InitInt();\n"
"\n"
" int m_iMyInt;\n"
" int m_bMyBool;\n"
"}\n"
"\n"
"c::c()\n"
"{\n"
" m_bMyBool = false;\n"
" InitInt();"
"}\n"
"\n"
"c::c(bool b)\n"
"{\n"
" m_bMyBool = b;\n"
" InitInt();\n"
"}\n"
"\n"
"void c::InitInt()\n"
"{\n"
" m_iMyInt = 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void initvar_constvar() void initvar_constvar()
{ {
check("class Fred\n"
"{\n"
"public:\n"
" const char *s;\n"
" Fred();\n"
"};\n"
"Fred::Fred() : s(NULL)\n"
"{ }");
ASSERT_EQUALS("", errout.str());
check("class Fred\n"
"{\n"
"public:\n"
" const char *s;\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{ s = NULL; }");
ASSERT_EQUALS("", errout.str());
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
"public:\n" "public:\n"
@ -324,6 +621,33 @@ private:
"Fred::Fred()\n" "Fred::Fred()\n"
"{ }"); "{ }");
ASSERT_EQUALS("[test.cpp:7]: (style) Member variable not initialized in the constructor 'Fred::s'\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (style) Member variable not initialized in the constructor 'Fred::s'\n", errout.str());
check("struct Fred\n"
"{\n"
" const char *s;\n"
" Fred();\n"
"};\n"
"Fred::Fred() : s(NULL)\n"
"{ }");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" const char *s;\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{ s = NULL; }");
ASSERT_EQUALS("", errout.str());
check("struct Fred\n"
"{\n"
" const char *s;\n"
" Fred();\n"
"};\n"
"Fred::Fred()\n"
"{ }");
ASSERT_EQUALS("[test.cpp:6]: (style) Member variable not initialized in the constructor 'Fred::s'\n", errout.str());
} }

View File

@ -142,6 +142,7 @@ private:
TEST_CASE(simplify_constants2); TEST_CASE(simplify_constants2);
TEST_CASE(findClassFunction1); TEST_CASE(findClassFunction1);
TEST_CASE(findClassFunction2);
TEST_CASE(vardecl1); TEST_CASE(vardecl1);
TEST_CASE(vardecl2); TEST_CASE(vardecl2);
@ -2254,7 +2255,7 @@ private:
const char code[] = const char code[] =
"class Fred" "class Fred"
"{\n" "{\n"
// "public:\n" "public:\n"
" Fred()\n" " Fred()\n"
" { }\n" " { }\n"
"};\n"; "};\n";
@ -2273,6 +2274,29 @@ private:
ASSERT_EQUALS(0, tok ? 1 : 0); ASSERT_EQUALS(0, tok ? 1 : 0);
} }
void findClassFunction2()
{
const char code[] =
"struct Fred"
"{\n"
" Fred()\n"
" { }\n"
"};\n";
// tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
int i;
i = 0;
const Token *tok = Tokenizer::findClassFunction(tokenizer.tokens(), "Fred", "%var%", i, true);
ASSERT_EQUALS(true, Token::simpleMatch(tok, "Fred ( ) {"));
tok = Tokenizer::findClassFunction(tok->next(), "Fred", "%var%", i, false);
ASSERT_EQUALS(0, tok ? 1 : 0);
}
void vardecl1() void vardecl1()
{ {
const char code[] = "unsigned int a, b;"; const char code[] = "unsigned int a, b;";