Skip to content

Commit 6b1a2dc

Browse files
committed
Fixed cppcheck-opensource#7788 (Varid missing for member variable in ctor of template class)
1 parent 7ec0e41 commit 6b1a2dc

2 files changed

Lines changed: 54 additions & 27 deletions

File tree

lib/tokenize.cpp

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,47 +2970,51 @@ void Tokenizer::setVarIdPass2()
29702970
std::map<const Token *, std::string> endOfScope;
29712971
std::list<std::string> scope;
29722972
std::list<const Token *> usingnamespaces;
2973-
for (Token *tok2 = list.front(); tok2; tok2 = tok2->next()) {
2974-
if (!tok2->previous() || Token::Match(tok2->previous(), "[;{}]")) {
2975-
if (Token::Match(tok2, "using namespace %name% ::|;")) {
2976-
const Token *endtok = tok2->tokAt(2);
2973+
for (Token *tok = list.front(); tok; tok = tok->next()) {
2974+
if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) {
2975+
if (Token::Match(tok, "using namespace %name% ::|;")) {
2976+
const Token *endtok = tok->tokAt(2);
29772977
while (Token::Match(endtok, "%name% ::"))
29782978
endtok = endtok->tokAt(2);
29792979
if (Token::Match(endtok, "%name% ;"))
2980-
usingnamespaces.push_back(tok2->tokAt(2));
2981-
} else if (Token::Match(tok2, "namespace %name% {")) {
2982-
scope.push_back(tok2->strAt(1));
2983-
endOfScope[tok2->linkAt(2)] = tok2->strAt(1);
2980+
usingnamespaces.push_back(tok->tokAt(2));
2981+
} else if (Token::Match(tok, "namespace %name% {")) {
2982+
scope.push_back(tok->strAt(1));
2983+
endOfScope[tok->linkAt(2)] = tok->strAt(1);
29842984
}
29852985
}
29862986

2987-
if (tok2->str() == "}") {
2988-
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok2);
2987+
if (tok->str() == "}") {
2988+
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok);
29892989
if (it != endOfScope.end())
29902990
scope.remove(it->second);
29912991
}
29922992

2993-
const Token* tok3 = nullptr;
2994-
if (Token::Match(tok2, "%name% :: ~| %name%"))
2995-
tok3 = tok2->next();
2996-
else if (Token::Match(tok2, "%name% <") && Token::Match(tok2->next()->findClosingBracket(),"> :: ~| %name%"))
2997-
tok3 = tok2->next()->findClosingBracket()->next();
2993+
Token* const tok1 = tok;
2994+
if (Token::Match(tok->previous(), "!!:: %name% :: ~| %name%"))
2995+
tok = tok->next();
2996+
else if (Token::Match(tok->previous(), "!!:: %name% <") && Token::Match(tok->next()->findClosingBracket(),"> :: ~| %name%"))
2997+
tok = tok->next()->findClosingBracket()->next();
29982998
else
29992999
continue;
30003000

3001-
while (Token::Match(tok3, ":: ~| %name%")) {
3002-
tok3 = tok3->next();
3003-
if (tok3->str() == "~")
3004-
tok3 = tok3->next();
3005-
tok3 = tok3->next();
3001+
while (Token::Match(tok, ":: ~| %name%")) {
3002+
tok = tok->next();
3003+
if (tok->str() == "~")
3004+
tok = tok->next();
3005+
else if (Token::Match(tok, "%name% <") && Token::Match(tok->next()->findClosingBracket(),"> :: ~| %name%"))
3006+
tok = tok->next()->findClosingBracket()->next();
3007+
else if (Token::Match(tok, "%name% ::"))
3008+
tok = tok->next();
3009+
else
3010+
break;
30063011
}
3007-
if (!tok3)
3008-
syntaxError(tok2);
3009-
const std::string& str3 = tok3->str();
3010-
if (str3 == "(")
3011-
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok2));
3012-
else if (str3 != "::" && tok2->strAt(-1) != "::") // Support only one depth
3013-
allMemberVars.push_back(Member(scope, usingnamespaces, tok2));
3012+
if (!tok)
3013+
syntaxError(tok1);
3014+
if (Token::Match(tok, "%name% ("))
3015+
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok1));
3016+
else
3017+
allMemberVars.push_back(Member(scope, usingnamespaces, tok1));
30143018
}
30153019
}
30163020

test/testvarid.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class TestVarID : public TestFixture {
126126
TEST_CASE(varid_in_class18); // #7127
127127
TEST_CASE(varid_in_class19);
128128
TEST_CASE(varid_in_class20); // #7267
129+
TEST_CASE(varid_in_class21); // #7788
129130
TEST_CASE(varid_namespace_1); // #7272
130131
TEST_CASE(varid_namespace_2); // #7000
131132
TEST_CASE(varid_initList);
@@ -1769,6 +1770,28 @@ class TestVarID : public TestFixture {
17691770
"8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, false, "test.cpp"));
17701771
}
17711772

1773+
void varid_in_class21() {
1774+
const char code[] = "template <typename t1,typename t2>\n"
1775+
"class A::B {\n"
1776+
" B();\n"
1777+
" int x;\n"
1778+
"};\n"
1779+
"\n"
1780+
"template <typename t1,typename t2>\n"
1781+
"A::B<t1,t2>::B() : x(9) {}";
1782+
1783+
const char expected[] = "1: template < typename t1 , typename t2 >\n"
1784+
"2: class A :: B {\n"
1785+
"3: B ( ) ;\n"
1786+
"4: int x@1 ;\n"
1787+
"5: } ;\n"
1788+
"6:\n"
1789+
"7: template < typename t1 , typename t2 >\n"
1790+
"8: A :: B < t1 , t2 > :: B ( ) : x@1 ( 9 ) { }\n";
1791+
1792+
ASSERT_EQUALS(expected, tokenize(code, false, "test.cpp"));
1793+
}
1794+
17721795
void varid_namespace_1() { // #7272
17731796
const char code[] = "namespace Blah {\n"
17741797
" struct foo { int x;};\n"

0 commit comments

Comments
 (0)