Fixed #6268 (False positive functionStatic (inconclusive) - nested namespaces)

This commit is contained in:
Robert Reif 2014-11-27 06:29:33 +01:00 committed by Daniel Marjamäki
parent 1779921306
commit 0dad8b64e8
3 changed files with 112 additions and 6 deletions

View File

@ -1067,15 +1067,42 @@ void Tokenizer::simplifyTypedef()
pattern1 = pattern;
if (pattern1.find("::") != std::string::npos) { // has a "something ::"
if (tok2->strAt(-1) == "::") {
tok2->tokAt(-2)->deleteNext();
globalScope = true;
Token *start = tok2;
size_t count = 0;
int back = int(classLevel) - 1;
bool good = true;
// check for extra qualification
while (back >= 0 && Token::Match(start->tokAt(-2), "%type% ::")) {
if (start->strAt(-2) == spaceInfo[back].className) {
start = start->tokAt(-2);
back--;
count++;
} else {
good = false;
break;
}
}
// check global namespace
if (good && back == 0 && start->strAt(-1) == "::")
good = false;
for (std::size_t i = classLevel; i < spaceInfo.size(); ++i) {
tok2->deleteNext(2);
if (good) {
// remove any extra qualification if present
while (count--)
tok2->tokAt(-3)->deleteNext(2);
// remove global namespace if present
if (tok2->strAt(-1) == "::") {
tok2->tokAt(-2)->deleteNext();
globalScope = true;
}
// remove qualification if present
for (std::size_t i = classLevel; i < spaceInfo.size(); ++i) {
tok2->deleteNext(2);
}
simplifyType = true;
}
simplifyType = true;
} else if ((inScope && !exitThisScope) || inMemberFunc) {
if (tok2->strAt(-1) == "::") {
// Don't replace this typename if it's preceded by "::" unless it's a namespace

View File

@ -144,6 +144,7 @@ private:
TEST_CASE(const61); // ticket #5606
TEST_CASE(const62); // ticket #5701
TEST_CASE(const63); // ticket #5983
TEST_CASE(const64); // ticket #6268
TEST_CASE(const_handleDefaultParameters);
TEST_CASE(const_passThisToMemberOfOtherClass);
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
@ -4911,6 +4912,21 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'A::clear' can be const.\n", errout.str());
}
void const64() {
checkConst("namespace B {\n"
" namespace D {\n"
" typedef int DKIPtr;\n"
" }\n"
" class ZClass {\n"
" void set(const ::B::D::DKIPtr& p) {\n"
" membervariable = p;\n"
" }\n"
" ::B::D::DKIPtr membervariable;\n"
" };\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void const_handleDefaultParameters() {
checkConst("struct Foo {\n"
" void foo1(int i, int j = 0) {\n"

View File

@ -144,6 +144,7 @@ private:
TEST_CASE(simplifyTypedef107); // ticket #3963 - bad code => segmentation fault
TEST_CASE(simplifyTypedef108); // ticket #4777
TEST_CASE(simplifyTypedef109); // ticket #1823 - rvalue reference
TEST_CASE(simplifyTypedef110); // ticket #6268
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -2398,6 +2399,68 @@ private:
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef110() {
const char code[] = "namespace A {\n"
" namespace B {\n"
" namespace D {\n"
" typedef int DKIPtr;\n"
" }\n"
" struct ZClass {\n"
" void set1(const A::B::D::DKIPtr& p) {\n"
" membervariable1 = p;\n"
" }\n"
" void set2(const ::A::B::D::DKIPtr& p) {\n"
" membervariable2 = p;\n"
" }\n"
" void set3(const B::D::DKIPtr& p) {\n"
" membervariable3 = p;\n"
" }\n"
" void set4(const ::B::D::DKIPtr& p) {\n"
" membervariable4 = p;\n"
" }\n"
" void set5(const C::D::DKIPtr& p) {\n"
" membervariable5 = p;\n"
" }\n"
" A::B::D::DKIPtr membervariable1;\n"
" ::A::B::D::DKIPtr membervariable2;\n"
" B::D::DKIPtr membervariable3;\n"
" ::B::D::DKIPtr membervariable4;\n"
" C::D::DKIPtr membervariable5;\n"
" };\n"
" }\n"
"}";
const char expected[] = "namespace A { "
"namespace B { "
"struct ZClass { "
"void set1 ( const int & p ) { "
"membervariable1 = p ; "
"} "
"void set2 ( const int & p ) { "
"membervariable2 = p ; "
"} "
"void set3 ( const int & p ) { "
"membervariable3 = p ; "
"} "
"void set4 ( const :: B :: D :: DKIPtr & p ) { "
"membervariable4 = p ; "
"} "
"void set5 ( const C :: D :: DKIPtr & p ) { "
"membervariable5 = p ; "
"} "
"int membervariable1 ; "
"int membervariable2 ; "
"int membervariable3 ; "
":: B :: D :: DKIPtr membervariable4 ; "
"C :: D :: DKIPtr membervariable5 ; "
"} ; "
"} "
"}";
checkSimplifyTypedef(code);
ASSERT_EQUALS(expected, tok(code));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1() {
{
const char code[] = "typedef void (*my_func)();\n"