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

This commit is contained in:
Robert Reif 2012-12-24 06:46:30 +01:00 committed by Daniel Marjamäki
parent 5f5eaf0763
commit 9a79961b6c
4 changed files with 35 additions and 5 deletions

View File

@ -367,6 +367,9 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
if (level == 0 && Token::Match(ftok, "%var% (")) { if (level == 0 && Token::Match(ftok, "%var% (")) {
if (ftok->strAt(2) != ")") if (ftok->strAt(2) != ")")
initVar(ftok->str(), scope, usage); initVar(ftok->str(), scope, usage);
} else if (level == 0 && Token::Match(ftok, "%var% {")) {
initVar(ftok->str(), scope, usage);
ftok = ftok->linkAt(1);
} else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x) } else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x)
assignVar(ftok->str(), scope, usage); assignVar(ftok->str(), scope, usage);

View File

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

View File

@ -53,6 +53,7 @@ private:
TEST_CASE(noConstructor6); // ticket #4386 TEST_CASE(noConstructor6); // ticket #4386
TEST_CASE(noConstructor7); // ticket #4391 TEST_CASE(noConstructor7); // ticket #4391
TEST_CASE(noConstructor8); // ticket #4404 TEST_CASE(noConstructor8); // ticket #4404
TEST_CASE(noConstructor9); // ticket #4419
TEST_CASE(operatorEq1); TEST_CASE(operatorEq1);
TEST_CASE(operatorEq2); TEST_CASE(operatorEq2);
@ -1913,6 +1914,17 @@ private:
ASSERT_EQUALS("", errout.str()); 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[]) { void checkNoMemset(const char code[]) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");

View File

@ -124,7 +124,8 @@ private:
TEST_CASE(uninitVarArray8); TEST_CASE(uninitVarArray8);
TEST_CASE(uninitVarArray2D); TEST_CASE(uninitVarArray2D);
TEST_CASE(uninitVarArray3D); TEST_CASE(uninitVarArray3D);
TEST_CASE(uninitVarCpp11Init); TEST_CASE(uninitVarCpp11Init1);
TEST_CASE(uninitVarCpp11Init2);
TEST_CASE(uninitVarStruct1); // ticket #2172 TEST_CASE(uninitVarStruct1); // ticket #2172
TEST_CASE(uninitVarStruct2); // ticket #838 TEST_CASE(uninitVarStruct2); // ticket #838
TEST_CASE(uninitVarUnion1); // ticket #3196 TEST_CASE(uninitVarUnion1); // ticket #3196
@ -1814,7 +1815,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void uninitVarCpp11Init() { void uninitVarCpp11Init1() {
check("class Foo {\n" check("class Foo {\n"
" std::vector<std::string> bar;\n" " std::vector<std::string> bar;\n"
"public:\n" "public:\n"
@ -1825,6 +1826,20 @@ private:
ASSERT_EQUALS("", errout.str()); 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"
"};");
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Fred::g' is not initialized in the constructor.\n", errout.str());
}
void uninitVarStruct1() { // ticket #2172 void uninitVarStruct1() { // ticket #2172
check("class A\n" check("class A\n"
"{\n" "{\n"