Fixed #2465 (False positive: not initialised variable, but there is default constructor for it.)
This commit is contained in:
parent
00b49a51da
commit
79b9939610
|
@ -411,12 +411,18 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
if (func->type == SymbolDatabase::Func::Constructor)
|
if (func->type == SymbolDatabase::Func::Constructor)
|
||||||
{
|
{
|
||||||
// check for no arguments: func ( )
|
// check for no arguments: func ( )
|
||||||
/** @todo check for arguments with default values someday */
|
|
||||||
if (func->argDef->next() == func->argDef->link())
|
if (func->argDef->next() == func->argDef->link())
|
||||||
{
|
{
|
||||||
hasDefaultConstructor = true;
|
hasDefaultConstructor = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** check for arguments with default values */
|
||||||
|
else if (func->argCount() == func->initializedArgCount())
|
||||||
|
{
|
||||||
|
hasDefaultConstructor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,6 +914,43 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok)
|
||||||
|
|
||||||
return tok2;
|
return tok2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
unsigned int SymbolDatabase::Func::argCount() const
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
if (argDef->link() != argDef->next())
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
for (const Token *tok = argDef->next(); tok && tok->next() && tok->next() != argDef->link(); tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == ",")
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int SymbolDatabase::Func::initializedArgCount() const
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
if (argDef->link() != argDef->next())
|
||||||
|
{
|
||||||
|
for (const Token *tok = argDef->next(); tok && tok->next() && tok->next() != argDef->link(); tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == "=")
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SymbolDatabase::SpaceInfo *nestedIn_) :
|
SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SymbolDatabase::SpaceInfo *nestedIn_) :
|
||||||
|
|
|
@ -117,6 +117,9 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int argCount() const;
|
||||||
|
unsigned int initializedArgCount() const;
|
||||||
|
|
||||||
const Token *tokenDef; // function name token in class definition
|
const Token *tokenDef; // function name token in class definition
|
||||||
const Token *argDef; // function argument start '(' in class definition
|
const Token *argDef; // function argument start '(' in class definition
|
||||||
const Token *token; // function name token in implementation
|
const Token *token; // function name token in implementation
|
||||||
|
|
|
@ -61,6 +61,7 @@ private:
|
||||||
TEST_CASE(uninitVar15);
|
TEST_CASE(uninitVar15);
|
||||||
TEST_CASE(uninitVar16);
|
TEST_CASE(uninitVar16);
|
||||||
TEST_CASE(uninitVar17);
|
TEST_CASE(uninitVar17);
|
||||||
|
TEST_CASE(uninitVar18); // ticket #2465
|
||||||
TEST_CASE(uninitVarEnum);
|
TEST_CASE(uninitVarEnum);
|
||||||
TEST_CASE(uninitVarStream);
|
TEST_CASE(uninitVarStream);
|
||||||
TEST_CASE(uninitVarTypedef);
|
TEST_CASE(uninitVarTypedef);
|
||||||
|
@ -2026,6 +2027,37 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Bar::foo' is not initialised in the constructor.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Bar::foo' is not initialised in the constructor.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uninitVar18() // ticket #2465
|
||||||
|
{
|
||||||
|
checkUninitVar("struct Altren\n"
|
||||||
|
"{\n"
|
||||||
|
" Altren(int _a = 0) : value(0) { }\n"
|
||||||
|
" int value;\n"
|
||||||
|
"};\n"
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" A() { }\n"
|
||||||
|
"private:\n"
|
||||||
|
" Altren value;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar("struct Altren\n"
|
||||||
|
"{\n"
|
||||||
|
" Altren(int _a) : value(0) { }\n"
|
||||||
|
" int value;\n"
|
||||||
|
"};\n"
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" A() { }\n"
|
||||||
|
"private:\n"
|
||||||
|
" Altren value;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'A::value' is not initialised in the constructor.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void uninitVarArray1()
|
void uninitVarArray1()
|
||||||
{
|
{
|
||||||
checkUninitVar("class John\n"
|
checkUninitVar("class John\n"
|
||||||
|
|
Loading…
Reference in New Issue