Fixed #6568: Scope for template class member function missing in symboldatabase
This commit is contained in:
parent
d5ad1def40
commit
4ceb24630d
|
@ -1301,7 +1301,6 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
(tok->previous()->isName() || tok->strAt(-1) == ">" || tok->strAt(-1) == "&" || tok->strAt(-1) == "*" || // Either a return type in front of tok
|
(tok->previous()->isName() || tok->strAt(-1) == ">" || tok->strAt(-1) == "&" || tok->strAt(-1) == "*" || // Either a return type in front of tok
|
||||||
tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok
|
tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok
|
||||||
outerScope->isClassOrStruct())) { // or a ctor/dtor
|
outerScope->isClassOrStruct())) { // or a ctor/dtor
|
||||||
|
|
||||||
const Token* tok1 = tok->previous();
|
const Token* tok1 = tok->previous();
|
||||||
|
|
||||||
// skip over destructor "~"
|
// skip over destructor "~"
|
||||||
|
@ -1312,6 +1311,8 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
while (Token::simpleMatch(tok1, "::")) {
|
while (Token::simpleMatch(tok1, "::")) {
|
||||||
if (Token::Match(tok1->tokAt(-1), "%name%"))
|
if (Token::Match(tok1->tokAt(-1), "%name%"))
|
||||||
tok1 = tok1->tokAt(-2);
|
tok1 = tok1->tokAt(-2);
|
||||||
|
else if (tok1->strAt(-1) == ">" && tok1->linkAt(-1) && Token::Match(tok1->linkAt(-1)->previous(), "%name%"))
|
||||||
|
tok1 = tok1->linkAt(-1)->tokAt(-2);
|
||||||
else
|
else
|
||||||
tok1 = tok1->tokAt(-1);
|
tok1 = tok1->tokAt(-1);
|
||||||
}
|
}
|
||||||
|
@ -1717,6 +1718,8 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
||||||
// skip class/struct name
|
// skip class/struct name
|
||||||
if (destructor)
|
if (destructor)
|
||||||
tok1 = (*tok)->tokAt(-3);
|
tok1 = (*tok)->tokAt(-3);
|
||||||
|
else if ((*tok)->strAt(-2) == ">" && (*tok)->linkAt(-2))
|
||||||
|
tok1 = (*tok)->linkAt(-2)->previous();
|
||||||
else
|
else
|
||||||
tok1 = (*tok)->tokAt(-2);
|
tok1 = (*tok)->tokAt(-2);
|
||||||
|
|
||||||
|
@ -1730,11 +1733,25 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
||||||
|
|
||||||
// back up to head of path
|
// back up to head of path
|
||||||
while (tok1 && tok1->previous() && tok1->previous()->str() == "::" &&
|
while (tok1 && tok1->previous() && tok1->previous()->str() == "::" &&
|
||||||
tok1->tokAt(-2) && tok1->tokAt(-2)->isName()) {
|
tok1->tokAt(-2) && (tok1->tokAt(-2)->isName() || (tok1->strAt(-2) == ">" && tok1->linkAt(-2)))) {
|
||||||
path = tok1->str() + " :: " + path;
|
if (tok1->strAt(-2) == ">") {
|
||||||
tok1 = tok1->tokAt(-2);
|
tok1 = tok1->tokAt(-2);
|
||||||
count++;
|
const Token * tok2 = tok1->previous();
|
||||||
path_length++;
|
path = ":: " + path;
|
||||||
|
if (tok2) {
|
||||||
|
do {
|
||||||
|
path = tok1->str() + " " + path;
|
||||||
|
tok1 = tok1->previous();
|
||||||
|
count++;
|
||||||
|
path_length++;
|
||||||
|
} while (tok1 != tok2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = tok1->str() + " :: " + path;
|
||||||
|
tok1 = tok1->tokAt(-2);
|
||||||
|
count++;
|
||||||
|
path_length++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok1 && count) {
|
if (tok1 && count) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
TEST_CASE(nullpointer24); // #5082 fp: chained assignment
|
TEST_CASE(nullpointer24); // #5082 fp: chained assignment
|
||||||
TEST_CASE(nullpointer25); // #5061
|
TEST_CASE(nullpointer25); // #5061
|
||||||
TEST_CASE(nullpointer26); // #3589
|
TEST_CASE(nullpointer26); // #3589
|
||||||
|
TEST_CASE(nullpointer27); // #6568
|
||||||
TEST_CASE(nullpointer_addressOf); // address of
|
TEST_CASE(nullpointer_addressOf); // address of
|
||||||
TEST_CASE(nullpointerSwitch); // #2626
|
TEST_CASE(nullpointerSwitch); // #2626
|
||||||
TEST_CASE(nullpointer_cast); // #4692
|
TEST_CASE(nullpointer_cast); // #4692
|
||||||
|
@ -1280,6 +1281,21 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nullpointer27() { // #6568
|
||||||
|
check("template<class Type>\n"
|
||||||
|
"class Foo {\n"
|
||||||
|
" Foo<Type>& operator = ( Type* );\n"
|
||||||
|
"};\n"
|
||||||
|
"template<class Type>\n"
|
||||||
|
"Foo<Type>& Foo<Type>::operator = ( Type* pointer_ ) {\n"
|
||||||
|
" pointer_=NULL;\n"
|
||||||
|
" *pointer_=0;\n"
|
||||||
|
" return *this;\n"
|
||||||
|
"}", false, "test.cpp", false);
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: pointer_\n"
|
||||||
|
"[test.cpp:8]: (error) Null pointer dereference\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void nullpointer_addressOf() { // address of
|
void nullpointer_addressOf() { // address of
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" struct X *x = 0;\n"
|
" struct X *x = 0;\n"
|
||||||
|
|
Loading…
Reference in New Issue