10221: Fix setVarId in template code (#3187)

The computation of the classname was not expecting templates. Simply
skipping the template part seems to fix the issue.
This commit is contained in:
Ken-Patrick Lehrmann 2021-03-29 12:16:02 +02:00 committed by GitHub
parent e23a967215
commit cddaa6d671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 4 deletions

View File

@ -4175,7 +4175,7 @@ void Tokenizer::setVarIdPass2()
while (tok->str() == "}" && !scopeInfo.empty() && tok == scopeInfo.back().bodyEnd)
scopeInfo.pop_back();
if (!Token::Match(tok, "namespace|class|struct %name% {|:|::"))
if (!Token::Match(tok, "namespace|class|struct %name% {|:|::|<"))
continue;
const std::string &scopeName(getScopeName(scopeInfo));
@ -4184,10 +4184,15 @@ void Tokenizer::setVarIdPass2()
std::list<const Token *> classnameTokens;
classnameTokens.push_back(tok->next());
const Token* tokStart = tok->tokAt(2);
while (Token::Match(tokStart, ":: %name%")) {
while (Token::Match(tokStart, ":: %name%") || tokStart->str() == "<") {
if (tokStart->str() == "<") {
// skip the template part
tokStart = tokStart->findClosingBracket()->next();
} else {
classnameTokens.push_back(tokStart->next());
tokStart = tokStart->tokAt(2);
}
}
std::string classname;
for (const Token *it : classnameTokens)

View File

@ -195,6 +195,7 @@ private:
TEST_CASE(varidclass19); // initializer list
TEST_CASE(varidclass20); // #7578: int (*p)[2]
TEST_CASE(varid_classnameshaddowsvariablename); // #3990
TEST_CASE(varid_classnametemplate); // #10221
TEST_CASE(varidenum1);
TEST_CASE(varidenum2);
@ -3211,6 +3212,37 @@ private:
}
void varid_classnametemplate() {
const char code[] = "template <typename T>\n"
"struct BBB {\n"
" struct inner;\n"
"};\n"
"\n"
"template <typename T>\n"
"struct BBB<T>::inner {\n"
" inner(int x);\n"
" int x;\n"
"};\n"
"\n"
"template <typename T>\n"
"BBB<T>::inner::inner(int x): x(x) {}\n";
const char expected[] = "1: template < typename T >\n"
"2: struct BBB {\n"
"3: struct inner ;\n"
"4: } ;\n"
"5:\n"
"6: template < typename T >\n"
"7: struct BBB < T > :: inner {\n"
"8: inner ( int x@1 ) ;\n"
"9: int x@2 ;\n"
"10: } ;\n"
"11:\n"
"12: template < typename T >\n"
"13: BBB < T > :: inner :: inner ( int x@3 ) : x@2 ( x@3 ) { }\n";
ASSERT_EQUALS(expected, tokenize(code));
}
void varidnamespace1() {
const char code[] = "namespace A {\n"
" char buf[20];\n"