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;
|
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"))
|
if (check && check->_tokenizer->isCPP() && Token::Match(tok, "throw|new"))
|
||||||
return false;
|
return false;
|
||||||
|
@ -3023,31 +3023,48 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
|
||||||
|
|
||||||
for (type = typeList.begin(); type != typeList.end(); ++type) {
|
for (type = typeList.begin(); type != typeList.end(); ++type) {
|
||||||
// do the names match?
|
// do the names match?
|
||||||
if (type->name() == typeTok->str()) {
|
if (type->name() != typeTok->str())
|
||||||
// check if type does not have a namespace
|
continue;
|
||||||
if (typeTok->strAt(-1) != "::") {
|
|
||||||
const Scope *parent = start;
|
|
||||||
|
|
||||||
// check if in same namespace
|
// check if type does not have a namespace
|
||||||
while (parent) {
|
if (typeTok->strAt(-1) != "::") {
|
||||||
// out of line class function belongs to class
|
const Scope *parent = start;
|
||||||
if (parent->type == Scope::eFunction && parent->functionOf)
|
|
||||||
parent = parent->functionOf;
|
|
||||||
else if (parent != type->enclosingScope)
|
|
||||||
parent = parent->nestedIn;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type->enclosingScope == parent)
|
// check if in same namespace
|
||||||
return &(*type);
|
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
|
if (type->enclosingScope == parent)
|
||||||
else {
|
|
||||||
// FIXME check if namespace path matches supplied path
|
|
||||||
return &(*type);
|
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
|
* @param typetok populated with pointer to the type token, if found
|
||||||
* @return true if tok points to a variable declaration, false otherwise
|
* @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;
|
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(namespaces1);
|
||||||
TEST_CASE(namespaces2);
|
TEST_CASE(namespaces2);
|
||||||
TEST_CASE(namespaces3); // #3854 - unknown macro
|
TEST_CASE(namespaces3); // #3854 - unknown macro
|
||||||
|
TEST_CASE(namespaces4);
|
||||||
|
|
||||||
TEST_CASE(tryCatch1);
|
TEST_CASE(tryCatch1);
|
||||||
|
|
||||||
|
@ -1537,6 +1538,16 @@ private:
|
||||||
ASSERT_EQUALS(Scope::eNamespace, db->scopeList.back().type);
|
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() {
|
void tryCatch1() {
|
||||||
const char str[] = "void foo() {\n"
|
const char str[] = "void foo() {\n"
|
||||||
" try { }\n"
|
" try { }\n"
|
||||||
|
|
Loading…
Reference in New Issue