Fixed #4698 (False positive: Uninitialized member variable warning with confusing namespaces)
This commit is contained in:
parent
f3f9ea2d09
commit
0e89620212
|
@ -2959,7 +2959,7 @@ static const Token* skipPointers(const Token* tok)
|
|||
return tok;
|
||||
}
|
||||
|
||||
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
|
||||
bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const
|
||||
{
|
||||
if (check && check->_tokenizer->isCPP() && Token::Match(tok, "throw|new"))
|
||||
return false;
|
||||
|
@ -3023,31 +3023,48 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
|
|||
|
||||
for (type = typeList.begin(); type != typeList.end(); ++type) {
|
||||
// do the names match?
|
||||
if (type->name() == typeTok->str()) {
|
||||
// check if type does not have a namespace
|
||||
if (typeTok->strAt(-1) != "::") {
|
||||
const Scope *parent = start;
|
||||
if (type->name() != typeTok->str())
|
||||
continue;
|
||||
|
||||
// check if in same namespace
|
||||
while (parent) {
|
||||
// out of line class function belongs to class
|
||||
if (parent->type == Scope::eFunction && parent->functionOf)
|
||||
parent = parent->functionOf;
|
||||
else if (parent != type->enclosingScope)
|
||||
parent = parent->nestedIn;
|
||||
else
|
||||
break;
|
||||
}
|
||||
// check if type does not have a namespace
|
||||
if (typeTok->strAt(-1) != "::") {
|
||||
const Scope *parent = start;
|
||||
|
||||
if (type->enclosingScope == parent)
|
||||
return &(*type);
|
||||
// check if in same namespace
|
||||
while (parent) {
|
||||
// out of line class function belongs to class
|
||||
if (parent->type == Scope::eFunction && parent->functionOf)
|
||||
parent = parent->functionOf;
|
||||
else if (parent != type->enclosingScope)
|
||||
parent = parent->nestedIn;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// type has a namespace
|
||||
else {
|
||||
// FIXME check if namespace path matches supplied path
|
||||
if (type->enclosingScope == parent)
|
||||
return &(*type);
|
||||
}
|
||||
|
||||
// type has a namespace
|
||||
else {
|
||||
bool match = true;
|
||||
const Scope *scope = type->enclosingScope;
|
||||
const Token *typeTok2 = typeTok->tokAt(-2);
|
||||
while (match && scope && Token::Match(typeTok2, "%any% ::")) {
|
||||
// A::B..
|
||||
if (typeTok2->isName() && typeTok2->str().find(":") == std::string::npos) {
|
||||
match &= bool(scope->className == typeTok2->str());
|
||||
typeTok2 = typeTok2->tokAt(-2);
|
||||
scope = scope->nestedIn;
|
||||
} else {
|
||||
// ::A..
|
||||
match &= bool(scope->type == Scope::eGlobal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match)
|
||||
return &(*type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -953,7 +953,7 @@ private:
|
|||
* @param typetok populated with pointer to the type token, if found
|
||||
* @return true if tok points to a variable declaration, false otherwise
|
||||
*/
|
||||
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const;
|
||||
bool isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const;
|
||||
|
||||
void findFunctionInBase(const std::string & name, size_t args, std::vector<const Function *> & matches) const;
|
||||
};
|
||||
|
|
|
@ -181,6 +181,7 @@ private:
|
|||
TEST_CASE(namespaces1);
|
||||
TEST_CASE(namespaces2);
|
||||
TEST_CASE(namespaces3); // #3854 - unknown macro
|
||||
TEST_CASE(namespaces4);
|
||||
|
||||
TEST_CASE(tryCatch1);
|
||||
|
||||
|
@ -1537,6 +1538,16 @@ private:
|
|||
ASSERT_EQUALS(Scope::eNamespace, db->scopeList.back().type);
|
||||
}
|
||||
|
||||
void namespaces4() { // #4698 - type lookup
|
||||
GET_SYMBOL_DB("struct A { int a; };\n"
|
||||
"namespace fred { struct A {}; }\n"
|
||||
"fred::A fredA;");
|
||||
const Variable *fredA = db->getVariableFromVarId(2U);
|
||||
ASSERT_EQUALS("fredA", fredA->name());
|
||||
const Type *fredAType = fredA->type();
|
||||
ASSERT_EQUALS(2U, fredAType->classDef->linenr());
|
||||
}
|
||||
|
||||
void tryCatch1() {
|
||||
const char str[] = "void foo() {\n"
|
||||
" try { }\n"
|
||||
|
|
Loading…
Reference in New Issue