Skip to content

Commit 0e89620

Browse files
committed
Fixed #4698 (False positive: Uninitialized member variable warning with confusing namespaces)
1 parent f3f9ea2 commit 0e89620

3 files changed

Lines changed: 50 additions & 22 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2959,7 +2959,7 @@ static const Token* skipPointers(const Token* tok)
29592959
return tok;
29602960
}
29612961

2962-
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
2962+
bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const
29632963
{
29642964
if (check && check->_tokenizer->isCPP() && Token::Match(tok, "throw|new"))
29652965
return false;
@@ -3023,31 +3023,48 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
30233023

30243024
for (type = typeList.begin(); type != typeList.end(); ++type) {
30253025
// do the names match?
3026-
if (type->name() == typeTok->str()) {
3027-
// check if type does not have a namespace
3028-
if (typeTok->strAt(-1) != "::") {
3029-
const Scope *parent = start;
3030-
3031-
// check if in same namespace
3032-
while (parent) {
3033-
// out of line class function belongs to class
3034-
if (parent->type == Scope::eFunction && parent->functionOf)
3035-
parent = parent->functionOf;
3036-
else if (parent != type->enclosingScope)
3037-
parent = parent->nestedIn;
3038-
else
3039-
break;
3040-
}
3026+
if (type->name() != typeTok->str())
3027+
continue;
30413028

3042-
if (type->enclosingScope == parent)
3043-
return &(*type);
3029+
// check if type does not have a namespace
3030+
if (typeTok->strAt(-1) != "::") {
3031+
const Scope *parent = start;
3032+
3033+
// check if in same namespace
3034+
while (parent) {
3035+
// out of line class function belongs to class
3036+
if (parent->type == Scope::eFunction && parent->functionOf)
3037+
parent = parent->functionOf;
3038+
else if (parent != type->enclosingScope)
3039+
parent = parent->nestedIn;
3040+
else
3041+
break;
30443042
}
30453043

3046-
// type has a namespace
3047-
else {
3048-
// FIXME check if namespace path matches supplied path
3044+
if (type->enclosingScope == parent)
30493045
return &(*type);
3046+
}
3047+
3048+
// type has a namespace
3049+
else {
3050+
bool match = true;
3051+
const Scope *scope = type->enclosingScope;
3052+
const Token *typeTok2 = typeTok->tokAt(-2);
3053+
while (match && scope && Token::Match(typeTok2, "%any% ::")) {
3054+
// A::B..
3055+
if (typeTok2->isName() && typeTok2->str().find(":") == std::string::npos) {
3056+
match &= bool(scope->className == typeTok2->str());
3057+
typeTok2 = typeTok2->tokAt(-2);
3058+
scope = scope->nestedIn;
3059+
} else {
3060+
// ::A..
3061+
match &= bool(scope->type == Scope::eGlobal);
3062+
break;
3063+
}
30503064
}
3065+
3066+
if (match)
3067+
return &(*type);
30513068
}
30523069
}
30533070

lib/symboldatabase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ class CPPCHECKLIB Scope {
953953
* @param typetok populated with pointer to the type token, if found
954954
* @return true if tok points to a variable declaration, false otherwise
955955
*/
956-
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const;
956+
bool isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const;
957957

958958
void findFunctionInBase(const std::string & name, size_t args, std::vector<const Function *> & matches) const;
959959
};

test/testsymboldatabase.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class TestSymbolDatabase: public TestFixture {
181181
TEST_CASE(namespaces1);
182182
TEST_CASE(namespaces2);
183183
TEST_CASE(namespaces3); // #3854 - unknown macro
184+
TEST_CASE(namespaces4);
184185

185186
TEST_CASE(tryCatch1);
186187

@@ -1537,6 +1538,16 @@ class TestSymbolDatabase: public TestFixture {
15371538
ASSERT_EQUALS(Scope::eNamespace, db->scopeList.back().type);
15381539
}
15391540

1541+
void namespaces4() { // #4698 - type lookup
1542+
GET_SYMBOL_DB("struct A { int a; };\n"
1543+
"namespace fred { struct A {}; }\n"
1544+
"fred::A fredA;");
1545+
const Variable *fredA = db->getVariableFromVarId(2U);
1546+
ASSERT_EQUALS("fredA", fredA->name());
1547+
const Type *fredAType = fredA->type();
1548+
ASSERT_EQUALS(2U, fredAType->classDef->linenr());
1549+
}
1550+
15401551
void tryCatch1() {
15411552
const char str[] = "void foo() {\n"
15421553
" try { }\n"

0 commit comments

Comments
 (0)