From 6a63104743ef546d0122cb5ad3fdde1a0931c7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 7 Jan 2012 09:28:26 +0100 Subject: [PATCH] Fixed #3320 (False positive: Member variable is not initialized in the constructor (namespaces).) --- lib/symboldatabase.cpp | 16 ++++++++++ test/testsymboldatabase.cpp | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4e37c78f0..7de7462ce 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -938,6 +938,22 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * (*scope)->className == scope1->nestedIn->className && !(*scope)->className.empty() && (*scope)->type == scope1->nestedIn->type)) { + + // nested scopes => check that they match + { + const Scope *s1 = *scope; + const Scope *s2 = scope1->nestedIn; + while (s1 && s2) { + if (s1->className != s2->className) + break; + s1 = s1->nestedIn; + s2 = s2->nestedIn; + } + // Not matching scopes + if (s1 || s2) + continue; + } + Scope *scope2 = scope1; while (scope2 && count > 0) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 033fdf625..b57834970 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -110,6 +110,9 @@ private: TEST_CASE(functionArgs1); TEST_CASE(functionArgs2); + TEST_CASE(namespaces1); + TEST_CASE(namespaces2); + TEST_CASE(symboldatabase1); TEST_CASE(symboldatabase2); TEST_CASE(symboldatabase3); // ticket #2000 @@ -657,6 +660,63 @@ private: ASSERT_EQUALS(4UL, a->dimension(1)); } + void namespaces1() { + GET_SYMBOL_DB("namespace fred {\n" + " namespace barney {\n" + " class X { X(int); };\n" + " }\n" + "}\n" + "namespace barney { X::X(int) { } }\n"); + + // Locate the scope for the class.. + const Scope *scope = NULL; + for (std::list::const_iterator it = db->scopeList.begin(); it != db->scopeList.end(); ++it) { + if (it->isClassOrStruct()) { + scope = &(*it); + break; + } + } + + ASSERT_EQUALS("X", scope->className); + + // The class has a constructor but the implementation is not seen + ASSERT_EQUALS(1U, scope->functionList.size()); + const Function *function = &(scope->functionList.front()); + ASSERT_EQUALS(false, function->hasBody); + } + + // based on namespaces1 but here the namespaces match + void namespaces2() { + GET_SYMBOL_DB("namespace fred {\n" + " namespace barney {\n" + " class X { X(int); };\n" + " }\n" + "}\n" + "namespace fred {\n" + " namespace barney {\n" + " X::X(int) { }\n" + " }\n" + "}\n"); + + // Locate the scope for the class.. + const Scope *scope = NULL; + for (std::list::const_iterator it = db->scopeList.begin(); it != db->scopeList.end(); ++it) { + if (it->isClassOrStruct()) { + scope = &(*it); + break; + } + } + + ASSERT_EQUALS("X", scope->className); + + // The class has a constructor but the implementation is not seen + ASSERT_EQUALS(1U, scope->functionList.size()); + const Function *function = &(scope->functionList.front()); + ASSERT_EQUALS("X", function->tokenDef->str()); + ASSERT_EQUALS(true, function->hasBody); + } + + void symboldatabase1() { check("namespace foo {\n" " class bar;\n"