Fixed #4789 (uninitMemberVar not found when constructor contains default parameters)

This commit is contained in:
Robert Reif 2013-05-18 18:33:24 +02:00 committed by Daniel Marjamäki
parent 1476787f40
commit 2c8360c607
2 changed files with 101 additions and 7 deletions

View File

@ -1069,31 +1069,61 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
// skip default value assignment
else if (first->next()->str() == "=") {
first = first->nextArgument();
if (first)
first = first->tokAt(-2);
if (second->next()->str() == "=") {
second = second->nextArgument();
if (second)
second = second->tokAt(-2);
if (!first || !second) { // End of argument list (first or second)
return !first && !second;
}
} else if (!first) { // End of argument list (first)
return second->next() && second->next()->str() == ")";
}
} else if (second->next()->str() == "=") {
second = second->nextArgument();
if (second)
second = second->tokAt(-2);
if (!first || !second) { // End of argument list (first or second)
return !first && !second;
}
}
// definition missing variable name
else if (first->next()->str() == "," && second->next()->str() != ",")
else if (first->next()->str() == "," && second->next()->str() != ",") {
second = second->next();
else if (first->next()->str() == ")" && second->next()->str() != ")")
// skip default value assignment
if (second->next()->str() == "=") {
while (!Token::Match(second->next(), ",|)"))
second = second->next();
}
} else if (first->next()->str() == ")" && second->next()->str() != ")") {
second = second->next();
else if (first->next()->str() == "[" && second->next()->str() != "[")
// skip default value assignment
if (second->next()->str() == "=") {
while (!Token::Match(second->next(), ",|)"))
second = second->next();
}
} else if (first->next()->str() == "[" && second->next()->str() != "[")
second = second->next();
// function missing variable name
else if (second->next()->str() == "," && first->next()->str() != ",")
else if (second->next()->str() == "," && first->next()->str() != ",") {
first = first->next();
else if (second->next()->str() == ")" && first->next()->str() != ")")
// skip default value assignment
if (first->next()->str() == "=") {
while (!Token::Match(first->next(), ",|)"))
first = first->next();
}
} else if (second->next()->str() == ")" && first->next()->str() != ")") {
first = first->next();
else if (second->next()->str() == "[" && first->next()->str() != "[")
// skip default value assignment
if (first->next()->str() == "=") {
while (!Token::Match(first->next(), ",|)"))
first = first->next();
}
} else if (second->next()->str() == "[" && first->next()->str() != "[")
first = first->next();
// argument list has different number of arguments

View File

@ -118,6 +118,7 @@ private:
TEST_CASE(uninitVar22); // ticket #3043
TEST_CASE(uninitVar23); // ticket #3702
TEST_CASE(uninitVar24); // ticket #3190
TEST_CASE(uninitVar25); // ticket #4789
TEST_CASE(uninitVarEnum);
TEST_CASE(uninitVarStream);
TEST_CASE(uninitVarTypedef);
@ -1826,6 +1827,69 @@ private:
"[test.cpp:20]: (warning) Member variable 'Sub::f' is not initialized in the constructor.\n", errout.str());
}
void uninitVar25() { // ticket #4789
check("struct A {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" A(int x = 0, int y = 0, int z = 0);\n"
"};\n"
"A::A(int x = 0, int y = 0, int z = 0) { } \n"
"struct B {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" B(int x = 0, int y = 0, int z = 0);\n"
"};\n"
"B::B(int x, int y, int z) { } \n"
"struct C {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" C(int, int, int);\n"
"};\n"
"C::C(int x = 0, int y = 0, int z = 0) { } \n"
"struct D {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" D(int, int, int);\n"
"};\n"
"D::D(int x, int y, int z) { } \n"
"struct E {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" E(int x, int y, int z);\n"
"};\n"
"E::E(int, int, int) { } \n"
"struct F {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" F(int x = 0, int y = 0, int z = 0);\n"
"};\n"
"F::F(int, int, int) { }\n", true);
ASSERT_EQUALS("[test.cpp:7]: (warning) Member variable 'A::a' is not initialized in the constructor.\n"
"[test.cpp:7]: (warning) Member variable 'A::b' is not initialized in the constructor.\n"
"[test.cpp:7]: (warning) Member variable 'A::c' is not initialized in the constructor.\n"
"[test.cpp:14]: (warning) Member variable 'B::a' is not initialized in the constructor.\n"
"[test.cpp:14]: (warning) Member variable 'B::b' is not initialized in the constructor.\n"
"[test.cpp:14]: (warning) Member variable 'B::c' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'C::a' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'C::b' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'C::c' is not initialized in the constructor.\n"
"[test.cpp:28]: (warning) Member variable 'D::a' is not initialized in the constructor.\n"
"[test.cpp:28]: (warning) Member variable 'D::b' is not initialized in the constructor.\n"
"[test.cpp:28]: (warning) Member variable 'D::c' is not initialized in the constructor.\n"
"[test.cpp:35]: (warning) Member variable 'E::a' is not initialized in the constructor.\n"
"[test.cpp:35]: (warning) Member variable 'E::b' is not initialized in the constructor.\n"
"[test.cpp:35]: (warning) Member variable 'E::c' is not initialized in the constructor.\n"
"[test.cpp:42]: (warning) Member variable 'F::a' is not initialized in the constructor.\n"
"[test.cpp:42]: (warning) Member variable 'F::b' is not initialized in the constructor.\n"
"[test.cpp:42]: (warning) Member variable 'F::c' is not initialized in the constructor.\n", errout.str());
}
void uninitVarArray1() {
check("class John\n"
"{\n"