Skip to content

Commit 8130fda

Browse files
committed
Implemented support for C++11 uniform initialization in several checks.
1 parent f3e0df7 commit 8130fda

File tree

5 files changed

+40
-36
lines changed

5 files changed

+40
-36
lines changed

lib/checkclass.cpp

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
447447
// Class constructor.. initializing variables like this
448448
// clKalle::clKalle() : var(value) { }
449449
if (initList) {
450-
if (level == 0 && Token::Match(ftok, "%var% (")) {
450+
if (level == 0 && Token::Match(ftok, "%var% {|(")) {
451451
if (ftok->str() != func.name()) {
452452
initVar(ftok->str(), scope, usage);
453453
} else { // c++11 delegate constructor
@@ -476,42 +476,14 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
476476
}
477477
}
478478
}
479-
} else if (level == 0 && Token::Match(ftok, "%var% {") && ftok->str() != "const" && Token::Match(ftok->next()->link()->next(), "%type%|,|{")) {
480-
if (ftok->str() != func.name()) {
481-
initVar(ftok->str(), scope, usage);
482-
} else { // c++11 delegate constructor
483-
const Function *member = scope->findFunction(ftok);
484-
// member function found
485-
if (member) {
486-
// recursive call
487-
// assume that all variables are initialized
488-
if (std::find(callstack.begin(), callstack.end(), member) != callstack.end()) {
489-
/** @todo false negative: just bail */
490-
assignAllVar(usage);
491-
return;
492-
}
493-
494-
// member function has implementation
495-
if (member->hasBody) {
496-
// initialize variable use list using member function
497-
callstack.push_back(member);
498-
initializeVarList(*member, callstack, scope, usage);
499-
callstack.pop_back();
500-
}
501-
502-
// there is a called member function, but it has no implementation, so we assume it initializes everything
503-
else {
504-
assignAllVar(usage);
505-
}
506-
}
507-
}
508-
ftok = ftok->linkAt(1);
479+
ftok = ftok->next();
480+
level++;
509481
} else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x)
510482
assignVar(ftok->str(), scope, usage);
511483

512484
else if (ftok->str() == "(")
513485
level++;
514-
else if (ftok->str() == ")")
486+
else if (ftok->str() == ")" || ftok->str() == "}")
515487
level--;
516488
else if (ftok->str() == "{") {
517489
if (level == 0)
@@ -1993,8 +1965,8 @@ void CheckClass::initializerListOrder()
19931965
tok = tok->next();
19941966

19951967
// find all variable initializations in list
1996-
while (tok && tok->str() != "{") {
1997-
if (Token::Match(tok, "%var% (")) {
1968+
while (tok && tok != func->functionScope->classStart) {
1969+
if (Token::Match(tok, "%var% (|{")) {
19981970
const Variable *var = info->getVariable(tok->str());
19991971

20001972
if (var)
@@ -2058,7 +2030,7 @@ void CheckClass::checkSelfInitialization()
20582030
continue;
20592031

20602032
for (; tok != scope->classStart; tok = tok->next()) {
2061-
if (Token::Match(tok, "[:,] %var% ( %var% )") && tok->next()->varId() && tok->next()->varId() == tok->tokAt(3)->varId()) {
2033+
if (Token::Match(tok, "[:,] %var% (|{ %var% )|}") && tok->next()->varId() && tok->next()->varId() == tok->tokAt(3)->varId()) {
20622034
selfInitializationError(tok, tok->strAt(1));
20632035
}
20642036
}

lib/checkuninitvar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
10771077
if (start && Token::simpleMatch(start->previous(), "catch ("))
10781078
continue;
10791079
}
1080-
if (i->nameToken()->strAt(1) == "(")
1080+
if (i->nameToken()->strAt(1) == "(" || i->nameToken()->strAt(1) == "{")
10811081
continue;
10821082
bool stdtype = _tokenizer->isC();
10831083
const Token* tok = i->typeStartToken();

test/testclass.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5563,6 +5563,14 @@ class TestClass : public TestFixture {
55635563
"};");
55645564
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::b' is in the wrong place in the initializer list.\n"
55655565
"[test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::a' is in the wrong place in the initializer list.\n", errout.str());
5566+
5567+
checkInitializerListOrder("class Fred {\n"
5568+
" int a, b, c;\n"
5569+
"public:\n"
5570+
" Fred() : c{0}, b{0}, a{0} { }\n"
5571+
"};");
5572+
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::b' is in the wrong place in the initializer list.\n"
5573+
"[test.cpp:4] -> [test.cpp:2]: (style, inconclusive) Member variable 'Fred::a' is in the wrong place in the initializer list.\n", errout.str());
55665574
}
55675575

55685576
void checkInitializationListUsage(const char code[]) {
@@ -5735,6 +5743,13 @@ class TestClass : public TestFixture {
57355743
"};");
57365744
ASSERT_EQUALS("[test.cpp:3]: (error) Member variable 'i' is initialized by itself.\n", errout.str());
57375745

5746+
checkSelfInitialization("class Fred {\n"
5747+
" int i;\n"
5748+
" Fred() : i{i} {\n"
5749+
" }\n"
5750+
"};");
5751+
ASSERT_EQUALS("[test.cpp:3]: (error) Member variable 'i' is initialized by itself.\n", errout.str());
5752+
57385753
checkSelfInitialization("class Fred {\n"
57395754
" int i;\n"
57405755
" Fred();\n"

test/testconstructors.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,15 @@ class TestConstructors : public TestFixture {
14611461
" int mi;\n"
14621462
"};");
14631463
ASSERT_EQUALS("", errout.str());
1464+
1465+
check("class Foo : public Bar\n"
1466+
"{\n"
1467+
"public:\n"
1468+
" explicit Foo(int i) : Bar{mi=i} { }\n"
1469+
"private:\n"
1470+
" int mi;\n"
1471+
"};");
1472+
ASSERT_EQUALS("", errout.str());
14641473
}
14651474

14661475
void uninitVar7() {

test/testuninitvar.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,14 @@ class TestUninitVar : public TestFixture {
615615
" return 1 + iter;\n"
616616
"}");
617617
ASSERT_EQUALS("", errout.str());
618+
619+
// C++11 style initialization
620+
checkUninitVar("int f() {\n"
621+
" int i = 0;\n"
622+
" int j{ i };\n"
623+
" return j;\n"
624+
"}");
625+
ASSERT_EQUALS("", errout.str());
618626
}
619627

620628
void uninitvar3() { // #3844

0 commit comments

Comments
 (0)