Fixed #7276 (VarId: Missing varId in template class constructor initialization lists)
This commit is contained in:
parent
760d5ab7f9
commit
414bdc30a9
114
lib/tokenize.cpp
114
lib/tokenize.cpp
|
@ -2852,22 +2852,27 @@ void Tokenizer::setVarId()
|
|||
std::list<Token *> allMemberVars;
|
||||
if (!isC()) {
|
||||
for (Token *tok2 = list.front(); tok2; tok2 = tok2->next()) {
|
||||
if (Token::Match(tok2, "%name% :: ~| %name%")) {
|
||||
const Token* tok3 = tok2->next();
|
||||
do {
|
||||
const Token* tok3 = nullptr;
|
||||
if (Token::Match(tok2, "%name% :: ~| %name%"))
|
||||
tok3 = tok2->next();
|
||||
else if (Token::Match(tok2, "%name% <") && Token::Match(tok2->next()->findClosingBracket(),"> :: ~| %name%"))
|
||||
tok3 = tok2->next()->findClosingBracket()->next();
|
||||
else
|
||||
continue;
|
||||
|
||||
while (Token::Match(tok3, ":: ~| %name%")) {
|
||||
tok3 = tok3->next();
|
||||
if (tok3->str() == "~")
|
||||
tok3 = tok3->next();
|
||||
if (tok3->str() == "~")
|
||||
tok3 = tok3->next();
|
||||
tok3 = tok3->next();
|
||||
} while (Token::Match(tok3, ":: ~| %name%"));
|
||||
if (!tok3)
|
||||
syntaxError(tok2);
|
||||
const std::string& str3 = tok3->str();
|
||||
if (str3 == "(")
|
||||
allMemberFunctions.push_back(tok2);
|
||||
else if (str3 != "::" && tok2->strAt(-1) != "::") // Support only one depth
|
||||
allMemberVars.push_back(tok2);
|
||||
tok3 = tok3->next();
|
||||
}
|
||||
if (!tok3)
|
||||
syntaxError(tok2);
|
||||
const std::string& str3 = tok3->str();
|
||||
if (str3 == "(")
|
||||
allMemberFunctions.push_back(tok2);
|
||||
else if (str3 != "::" && tok2->strAt(-1) != "::") // Support only one depth
|
||||
allMemberVars.push_back(tok2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2935,50 +2940,57 @@ void Tokenizer::setVarId()
|
|||
for (std::list<Token *>::iterator func = allMemberFunctions.begin(); func != allMemberFunctions.end(); ++func) {
|
||||
Token *tok2 = *func;
|
||||
|
||||
if (!Token::Match(tok2, classname.c_str()))
|
||||
continue;
|
||||
|
||||
if (Token::Match(tok2, "%name% <"))
|
||||
tok2 = tok2->next()->findClosingBracket();
|
||||
|
||||
// Found a class function..
|
||||
if (Token::Match(tok2, funcpattern.c_str())) {
|
||||
// Goto the end parentheses..
|
||||
tok2 = tok2->tokAt(nestedCount*2);
|
||||
if (tok2->str() == "~")
|
||||
tok2 = tok2->linkAt(2);
|
||||
else
|
||||
tok2 = tok2->linkAt(1);
|
||||
if (!Token::Match(tok2, "%any% :: ~| %name%"))
|
||||
continue;
|
||||
|
||||
// If this is a function implementation.. add it to funclist
|
||||
Token * start = const_cast<Token *>(isFunctionHead(tok2, "{"));
|
||||
if (start) {
|
||||
setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, &_varId);
|
||||
}
|
||||
// Goto the end parentheses..
|
||||
tok2 = tok2->tokAt(nestedCount*2);
|
||||
if (tok2->str() == "~")
|
||||
tok2 = tok2->linkAt(2);
|
||||
else
|
||||
tok2 = tok2->linkAt(1);
|
||||
|
||||
if (Token::Match(tok2, ") %name% ("))
|
||||
tok2 = tok2->linkAt(2);
|
||||
// If this is a function implementation.. add it to funclist
|
||||
Token * start = const_cast<Token *>(isFunctionHead(tok2, "{"));
|
||||
if (start) {
|
||||
setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, &_varId);
|
||||
}
|
||||
|
||||
// constructor with initializer list
|
||||
if (Token::Match(tok2, ") : %name%")) {
|
||||
Token *tok3 = tok2;
|
||||
while (Token::Match(tok3, "[)}] [,:]")) {
|
||||
if (Token::Match(tok2, ") %name% ("))
|
||||
tok2 = tok2->linkAt(2);
|
||||
|
||||
// constructor with initializer list
|
||||
if (Token::Match(tok2, ") : %name%")) {
|
||||
Token *tok3 = tok2;
|
||||
while (Token::Match(tok3, "[)}] [,:]")) {
|
||||
tok3 = tok3->tokAt(2);
|
||||
while (Token::Match(tok3, "%name% :: %name%"))
|
||||
tok3 = tok3->tokAt(2);
|
||||
while (Token::Match(tok3, "%name% :: %name%"))
|
||||
tok3 = tok3->tokAt(2);
|
||||
if (!Token::Match(tok3, "%name% (|{|<"))
|
||||
break;
|
||||
if (!Token::Match(tok3, "%name% (|{|<"))
|
||||
break;
|
||||
|
||||
// set varid
|
||||
std::map<std::string, unsigned int>::const_iterator varpos = thisClassVars.find(tok3->str());
|
||||
if (varpos != thisClassVars.end())
|
||||
tok3->varId(varpos->second);
|
||||
// set varid
|
||||
std::map<std::string, unsigned int>::const_iterator varpos = thisClassVars.find(tok3->str());
|
||||
if (varpos != thisClassVars.end())
|
||||
tok3->varId(varpos->second);
|
||||
|
||||
// goto end of var
|
||||
if (tok3->strAt(1) == "<") {
|
||||
tok3 = tok3->next()->findClosingBracket();
|
||||
if (tok3 && tok3->next() && tok3->next()->link())
|
||||
tok3 = tok3->next()->link();
|
||||
} else
|
||||
tok3 = tok3->linkAt(1);
|
||||
}
|
||||
if (Token::Match(tok3, ")|} {")) {
|
||||
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, &_varId);
|
||||
}
|
||||
// goto end of var
|
||||
if (tok3->strAt(1) == "<") {
|
||||
tok3 = tok3->next()->findClosingBracket();
|
||||
if (tok3 && tok3->next() && tok3->next()->link())
|
||||
tok3 = tok3->next()->link();
|
||||
} else
|
||||
tok3 = tok3->linkAt(1);
|
||||
}
|
||||
if (Token::Match(tok3, ")|} {")) {
|
||||
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, &_varId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,6 @@ private:
|
|||
TEST_CASE(removeVoidFromFunction);
|
||||
|
||||
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
|
||||
TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault
|
||||
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
|
||||
|
||||
// #3069 : for loop with 1 iteration
|
||||
|
@ -3951,12 +3950,6 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void simplifyVarDecl2() { // ticket # 2834 segmentation fault
|
||||
const char code[] = "std::vector<int>::iterator";
|
||||
tok(code, false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void return_strncat() {
|
||||
{
|
||||
const char code[] = "char *f()\n"
|
||||
|
|
|
@ -121,6 +121,7 @@ private:
|
|||
TEST_CASE(varid_in_class17); // #6056 - no varid for member functions
|
||||
TEST_CASE(varid_in_class18); // #7127
|
||||
TEST_CASE(varid_in_class19);
|
||||
TEST_CASE(varid_in_class20); // #7267
|
||||
TEST_CASE(varid_initList);
|
||||
TEST_CASE(varid_initListWithBaseTemplate);
|
||||
TEST_CASE(varid_initListWithScope);
|
||||
|
@ -1805,6 +1806,27 @@ private:
|
|||
"7: }\n", tokenize(code, false, "test.cpp"));
|
||||
}
|
||||
|
||||
void varid_in_class20() {
|
||||
const char code[] = "template<class C> class cacheEntry {\n"
|
||||
"protected:\n"
|
||||
" int m_key;\n"
|
||||
"public:\n"
|
||||
" cacheEntry();\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<class C> cacheEntry<C>::cacheEntry() : m_key() {}";
|
||||
|
||||
ASSERT_EQUALS("\n\n##file 0\n"
|
||||
"1: template < class C > class cacheEntry {\n"
|
||||
"2: protected:\n"
|
||||
"3: int m_key@1 ;\n"
|
||||
"4: public:\n"
|
||||
"5: cacheEntry ( ) ;\n"
|
||||
"6: } ;\n"
|
||||
"7:\n"
|
||||
"8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, false, "test.cpp"));
|
||||
}
|
||||
|
||||
void varid_initList() {
|
||||
const char code1[] = "class A {\n"
|
||||
" A() : x(0) {}\n"
|
||||
|
|
Loading…
Reference in New Issue