Fixed #6568: Scope for template class member function missing in symboldatabase

This commit is contained in:
Robert Reif 2015-04-09 21:01:47 +02:00 committed by PKEuS
parent d5ad1def40
commit 4ceb24630d
2 changed files with 39 additions and 6 deletions

View File

@ -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) {

View File

@ -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"