Tokenizer: add daca debug messages when right angle brackets in templates are not handled well

This commit is contained in:
Daniel Marjamäki 2020-11-29 16:07:56 +01:00
parent 3eaa76e832
commit 8a1c16a560
6 changed files with 56 additions and 36 deletions

View File

@ -234,30 +234,6 @@ TemplateSimplifier::~TemplateSimplifier()
{
}
void TemplateSimplifier::fixAngleBrackets()
{
for (Token *tok = mTokenList.front(); tok; tok = tok->next()) {
// Ticket #6181: normalize C++11 template parameter list closing syntax
if (tok->str() == "<" && templateParameters(tok)) {
Token *endTok = tok->findClosingBracket();
if (endTok && endTok->str() == ">>") {
endTok->str(">");
endTok->insertToken(">");
} else if (endTok && endTok->str() == ">>=") {
endTok->str(">");
endTok->insertToken("=");
endTok->insertToken(">");
}
} else if (Token::Match(tok, "class|struct|union|=|:|public|protected|private %name% <")) {
Token *endTok = tok->tokAt(2)->findClosingBracket();
if (Token::Match(endTok, ">> ;|{|%type%")) {
endTok->str(">");
endTok->insertToken(">");
}
}
}
}
void TemplateSimplifier::cleanupAfterSimplify()
{
bool goback = false;

View File

@ -331,11 +331,6 @@ public:
*/
void simplifyTemplateArgs(Token *start, Token *end);
/** Fix angle brackets.
* foo < bar < >> => foo < bar < > >
*/
void fixAngleBrackets();
private:
/**
* Get template declarations

View File

@ -4371,8 +4371,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
simplifyAsm();
// foo < bar < >> => foo < bar < > >
if (isCPP())
mTemplateSimplifier->fixAngleBrackets();
if (isCPP() || mSettings->daca)
splitTemplateRightAngleBrackets(!isCPP());
// Remove extra "template" tokens that are not used by cppcheck
removeExtraTemplateKeywords();
@ -5165,6 +5165,48 @@ void Tokenizer::removeExtraTemplateKeywords()
}
}
static std::string getExpression(const Token *tok) {
std::string line;
for (const Token *prev = tok->previous(); prev && !Token::Match(prev, "[;{}]"); prev = prev->previous())
line = prev->str() + " " + line;
line += "!!!" + tok->str() + "!!!";
for (const Token *next = tok->next(); next && !Token::Match(next, "[;{}]"); next = next->next())
line = line + " " + next->str();
return line;
}
void Tokenizer::splitTemplateRightAngleBrackets(bool check)
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
// Ticket #6181: normalize C++11 template parameter list closing syntax
if (tok->str() == "<" && mTemplateSimplifier->templateParameters(tok)) {
Token *endTok = tok->findClosingBracket();
if (check && endTok) {
reportError(tok, Severity::debug, "wrongSplitTemplateRightAngleBrackets", "bad closing bracket for !!!<!!!: " + getExpression(tok), false);
continue;
}
if (endTok && endTok->str() == ">>") {
endTok->str(">");
endTok->insertToken(">");
} else if (endTok && endTok->str() == ">>=") {
endTok->str(">");
endTok->insertToken("=");
endTok->insertToken(">");
}
} else if (Token::Match(tok, "class|struct|union|=|:|public|protected|private %name% <")) {
Token *endTok = tok->tokAt(2)->findClosingBracket();
if (check && endTok) {
reportError(tok, Severity::debug, "wrongSplitTemplateRightAngleBrackets", "bad closing bracket for !!!<!!!: " + getExpression(tok), false);
continue;
}
if (Token::Match(endTok, ">> ;|{|%type%")) {
endTok->str(">");
endTok->insertToken(">");
}
}
}
}
void Tokenizer::removeMacrosInGlobalScope()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {

View File

@ -176,6 +176,13 @@ public:
*/
void removeExtraTemplateKeywords();
/** Split up template right angle brackets.
* foo < bar < >> => foo < bar < > >
*/
void splitTemplateRightAngleBrackets(bool check);
/**
* Deletes dead code between 'begin' and 'end'.
* In general not everything can be erased, such as:

View File

@ -4739,7 +4739,7 @@ private:
std::istringstream istr(code);
tokenizer.createTokens(istr, "test.cpp");
tokenizer.createLinks();
tokenizer.mTemplateSimplifier->fixAngleBrackets();
tokenizer.splitTemplateRightAngleBrackets(false);
for (const Token *tok1 = tokenizer.tokens(); tok1; tok1 = tok1->next()) {
if (tok1->str() == "var1")
@ -4798,7 +4798,7 @@ private:
std::istringstream istr(code);
tokenizer.createTokens(istr, "test.cpp");
tokenizer.createLinks();
tokenizer.mTemplateSimplifier->fixAngleBrackets();
tokenizer.splitTemplateRightAngleBrackets(false);
const Token *_tok = tokenizer.tokens();
for (unsigned i = 0 ; i < offset ; ++i)
@ -4868,7 +4868,7 @@ private:
std::istringstream istr(code);
tokenizer.createTokens(istr, "test.cpp");
tokenizer.createLinks();
tokenizer.mTemplateSimplifier->fixAngleBrackets();
tokenizer.splitTemplateRightAngleBrackets(false);
const Token *_tok = tokenizer.tokens();
for (unsigned i = 0 ; i < offset ; ++i)

View File

@ -348,7 +348,7 @@ private:
TEST_CASE(functionAttributeBefore);
TEST_CASE(functionAttributeAfter);
TEST_CASE(fixAngleBrackets);
TEST_CASE(splitTemplateRightAngleBrackets);
TEST_CASE(cpp03template1);
TEST_CASE(cpp0xtemplate1);
@ -5272,7 +5272,7 @@ private:
ASSERT(func5 && func5->isAttributeNoreturn());
}
void fixAngleBrackets() {
void splitTemplateRightAngleBrackets() {
{
const char *code = "; z = x < 0 ? x >> y : x >> y;";
ASSERT_EQUALS("; z = x < 0 ? x >> y : x >> y ;", tokenizeAndStringify(code));