Fixed #4419 (False positive: Class does not have a constructor)

This commit is contained in:
Robert Reif 2012-12-27 17:21:30 +01:00 committed by Daniel Marjamäki
parent 3e6d601982
commit a43ae677d7
4 changed files with 37 additions and 6 deletions

View File

@ -359,7 +359,6 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
bool initList = true;
const Token *ftok = func.arg->link()->next();
int level = 0;
for (; ftok != func.functionScope->classEnd; ftok = ftok->next()) {
// Class constructor.. initializing variables like this
// clKalle::clKalle() : var(value) { }
@ -367,6 +366,9 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
if (level == 0 && Token::Match(ftok, "%var% (")) {
if (ftok->strAt(2) != ")")
initVar(ftok->str(), scope, usage);
} else if (level == 0 && Token::Match(ftok, "%var% {") && ftok->str() != "const") {
initVar(ftok->str(), scope, usage);
ftok = ftok->linkAt(1);
} else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x)
assignVar(ftok->str(), scope, usage);

View File

@ -923,7 +923,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok
outerScope->isClassOrStruct()) && // or a ctor/dtor
(Token::Match(tok->next()->link(), ") const| ;|{|=") ||
Token::Match(tok->next()->link(), ") : ::| %var% (|::"))) {
Token::Match(tok->next()->link(), ") : ::| %var% (|::|<|{"))) {
*funcStart = tok;
*argStart = tok->next();
return true;
@ -1258,8 +1258,8 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok)
Scope *new_scope = &scopeList.back();
// skip to start of function
while (tok1 && tok1->str() != "{") {
if (tok1->str() == "(")
while (tok1 && ((tok1->str() != "{") || (tok1->previous() && tok1->previous()->isName() && tok1->strAt(-1) != "const"))) {
if (tok1->str() == "(" || tok1->str() == "{")
tok1 = tok1->link();
tok1 = tok1->next();
}

View File

@ -53,6 +53,7 @@ private:
TEST_CASE(noConstructor6); // ticket #4386
TEST_CASE(noConstructor7); // ticket #4391
TEST_CASE(noConstructor8); // ticket #4404
TEST_CASE(noConstructor9); // ticket #4419
TEST_CASE(operatorEq1);
TEST_CASE(operatorEq2);
@ -1913,6 +1914,17 @@ private:
ASSERT_EQUALS("", errout.str());
}
void noConstructor9() {
// ticket #4419
checkNoConstructor("class CGreeting : public CGreetingBase<char> {\n"
"public:\n"
" CGreeting() : CGreetingBase<char>(), MessageSet(false) {}\n"
"private:\n"
" bool MessageSet;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
}
void checkNoMemset(const char code[]) {
// Clear the error log
errout.str("");

View File

@ -124,7 +124,8 @@ private:
TEST_CASE(uninitVarArray8);
TEST_CASE(uninitVarArray2D);
TEST_CASE(uninitVarArray3D);
TEST_CASE(uninitVarCpp11Init);
TEST_CASE(uninitVarCpp11Init1);
TEST_CASE(uninitVarCpp11Init2);
TEST_CASE(uninitVarStruct1); // ticket #2172
TEST_CASE(uninitVarStruct2); // ticket #838
TEST_CASE(uninitVarUnion1); // ticket #3196
@ -1814,7 +1815,7 @@ private:
ASSERT_EQUALS("", errout.str());
}
void uninitVarCpp11Init() {
void uninitVarCpp11Init1() {
check("class Foo {\n"
" std::vector<std::string> bar;\n"
"public:\n"
@ -1825,6 +1826,22 @@ private:
ASSERT_EQUALS("", errout.str());
}
void uninitVarCpp11Init2() {
check("class Fred {\n"
" struct Foo {\n"
" int a;\n"
" bool b;\n"
" };\n"
" Foo f;\n"
" float g;\n"
"public:\n"
" Fred() : f{0, true} { }\n"
" float get() const\n"
"};\n"
"float Fred::get() const { return g; }\n");
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Fred::g' is not initialized in the constructor.\n", errout.str());
}
void uninitVarStruct1() { // ticket #2172
check("class A\n"
"{\n"