Skip to content

Commit

Permalink
Fix #12676 (Tokenizer::setVarid: varid can be set wrongly for member …
Browse files Browse the repository at this point in the history
…in template class if member is used in uninstantiated constructor with initialization list) (danmar#6392)
  • Loading branch information
danmar committed May 13, 2024
1 parent a9e479a commit 5d17cc2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
7 changes: 5 additions & 2 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5167,12 +5167,15 @@ void Tokenizer::setVarIdPass2()
if (tok2->strAt(-1) == ")")
setVarIdClassFunction(scopeName2 + classname, tok2, tok2->link(), thisClassVars, structMembers, mVarId);
tok2 = tok2->link();
} else if (Token::Match(tok2, "( %name%|)") && !Token::Match(tok2->link(), "(|[")) {
} else if (Token::Match(tok2, "( %name%|)")) {
tok2 = tok2->link();

// Skip initialization list
if (Token::simpleMatch(tok2, ") :"))
if (Token::simpleMatch(tok2, ") :")) {
tok2 = skipInitializerList(tok2->next());
if (Token::simpleMatch(tok2, "{"))
tok2 = tok2->link();
}
}
}

Expand Down
67 changes: 67 additions & 0 deletions test/testvarid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class TestVarID : public TestFixture {
TEST_CASE(varid68); // #11740 - switch (str_chars(&strOut)[0])
TEST_CASE(varid69);
TEST_CASE(varid70); // #12660 - function
TEST_CASE(varid71); // #12676 - wrong varid in uninstantiated templated constructor
TEST_CASE(varid_for_1);
TEST_CASE(varid_for_2);
TEST_CASE(varid_cpp_keywords_in_c_code);
Expand Down Expand Up @@ -1294,6 +1295,72 @@ class TestVarID : public TestFixture {
ASSERT_EQUALS(expected3, tokenize(code3, true));
}

void varid71() {
const char code[] = "namespace myspace {\n"
"\n"
"template <typename T>\n"
"class CounterTest {\n"
"public:\n"
" CounterTest(T _obj);\n"
" template <typename T2>\n"
" CounterTest(const CounterTest<T2>& ptr);\n"
" T obj;\n"
" int count;\n"
"};\n"
"\n"
"template <typename T>\n"
"CounterTest<T>::CounterTest(T _obj) : obj(_obj) {\n"
" count = 0;\n"
"}\n"
"\n"
"template <typename T>\n"
"template <typename T2>\n"
"CounterTest<T>::CounterTest(const CounterTest<T2>& p) : obj(0) {\n"
" count = p.count;\n"
"}\n"
"\n"
"}\n"
"\n"
"using namespace myspace;\n"
"CounterTest<int> myobj(0);\n";
const char expected[] = "1: namespace myspace {\n"
"2:\n"
"3: class CounterTest<int> ;\n"
"4:\n"
"|\n"
"17:\n"
"18: template < typename T >\n"
"19: template < typename T2 >\n"
"20: CounterTest < T > :: CounterTest ( const CounterTest < T2 > & p@1 ) : obj ( 0 ) {\n"
"21: count = p@1 . count@2 ;\n"
"22: }\n"
"23:\n"
"24: }\n"
"25:\n"
"26: using namespace myspace ;\n"
"27: myspace :: CounterTest<int> myobj@3 ( 0 ) ;\n"
"4: class myspace :: CounterTest<int> {\n"
"5: public:\n"
"6: CounterTest<int> ( int _obj@4 ) ;\n"
"7: template < typename T2 >\n"
"8: CounterTest<int> ( const myspace :: CounterTest < T2 > & ptr@5 ) ;\n"
"9: int obj@6 ;\n"
"10: int count@7 ;\n"
"11: } ;\n"
"12:\n"
"13:\n"
"14: myspace :: CounterTest<int> :: CounterTest<int> ( int _obj@8 ) : obj@6 ( _obj@8 ) {\n"
"15: count@7 = 0 ;\n"
"16: }\n"
"17:\n"
"18:\n"
"19:\n"
"20: myspace :: CounterTest<int> :: CounterTest<int> ( const myspace :: CounterTest < T2 > & p@9 ) : obj@6 ( 0 ) {\n"
"21: count@7 = p@9 . count@10 ;\n"
"22: }\n";
ASSERT_EQUALS(expected, tokenize(code, true));
}

void varid_for_1() {
const char code[] = "void foo(int a, int b) {\n"
" for (int a=1,b=2;;) {}\n"
Expand Down

0 comments on commit 5d17cc2

Please sign in to comment.