diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 36514601b..ad33e718e 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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; diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index 504836893..aa1bb074c 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -331,11 +331,6 @@ public: */ void simplifyTemplateArgs(Token *start, Token *end); - /** Fix angle brackets. - * foo < bar < >> => foo < bar < > > - */ - void fixAngleBrackets(); - private: /** * Get template declarations diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d64dc87fe..cea95788d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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 !!!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 !!!> ;|{|%type%")) { + endTok->str(">"); + endTok->insertToken(">"); + } + } + } +} + void Tokenizer::removeMacrosInGlobalScope() { for (Token *tok = list.front(); tok; tok = tok->next()) { diff --git a/lib/tokenize.h b/lib/tokenize.h index ae369d280..5a21be2aa 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -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: diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index ec51a3bb6..aaf6a3659 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -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) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b24e1ba9e..9b57d1f24 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -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));