Fixed #1093 (False positive: missing constructor)
This commit is contained in:
parent
8a1940e043
commit
e7c0e4d482
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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..
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue