diff --git a/lib/token.cpp b/lib/token.cpp index 9727cc283..a36a4a64f 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1021,7 +1021,7 @@ void Token::function(const Function *f) tokType(eName); } -void Token::insertToken(const std::string &tokenStr, const std::string &originalNameStr, bool prepend) +Token* Token::insertToken(const std::string& tokenStr, const std::string& originalNameStr, bool prepend) { Token *newToken; if (mStr.empty()) @@ -1072,11 +1072,11 @@ void Token::insertToken(const std::string &tokenStr, const std::string &original while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept")) tok1 = tok1->previous(); if (tok1->strAt(-1) != ")") - return; + return newToken; } else if (Token::Match(newToken->tokAt(-2), ":|, %name%")) { tok1 = tok1->tokAt(-2); if (tok1->strAt(-1) != ")") - return; + return newToken; } if (tok1->strAt(-1) == ">") tok1 = tok1->previous()->findOpeningBracket(); @@ -1149,6 +1149,7 @@ void Token::insertToken(const std::string &tokenStr, const std::string &original } } } + return newToken; } void Token::eraseTokens(Token *begin, const Token *end) diff --git a/lib/token.h b/lib/token.h index 88de794fc..23b16c871 100644 --- a/lib/token.h +++ b/lib/token.h @@ -810,7 +810,12 @@ public: * @param prepend Insert the new token before this token when it's not * the first one on the tokens list. */ - void insertToken(const std::string &tokenStr, const std::string &originalNameStr=emptyString, bool prepend=false); + Token* insertToken(const std::string& tokenStr, const std::string& originalNameStr = emptyString, bool prepend = false); + + Token* insertTokenBefore(const std::string& tokenStr, const std::string& originalNameStr = emptyString) + { + return insertToken(tokenStr, originalNameStr, true); + } Token *previous() const { return mPrevious; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a2067add6..99bbca07e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4540,9 +4540,12 @@ void Tokenizer::createLinks2() continue; } - if (token->str() == ">>") { + if (token->str() == ">>" && top1 && top2) { type.pop(); type.pop(); + // Split the angle brackets + token->str(">"); + Token::createMutualLinks(top1, token->insertTokenBefore(">")); Token::createMutualLinks(top2, token); if (templateTokens.size() == 2 && (top1 == templateTokens.top() || top2 == templateTokens.top())) { templateTokens.pop(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 15982be83..7b3e84cba 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3336,6 +3336,32 @@ private: ASSERT_EQUALS(true, tok2->link() == tok1); } + { + // #10552 + const char code[] = "v.value>()\n"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + const Token* tok1 = Token::findsimplematch(tokenizer.tokens(), "< QPair"); + const Token* tok2 = Token::findsimplematch(tok1, "> ("); + ASSERT_EQUALS(true, tok1->link() == tok2); + ASSERT_EQUALS(true, tok2->link() == tok1); + } + + { + // #10552 + const char code[] = "v.value>()\n"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + const Token* tok1 = Token::findsimplematch(tokenizer.tokens(), "< int"); + const Token* tok2 = Token::findsimplematch(tok1, "> > ("); + ASSERT_EQUALS(true, tok1->link() == tok2); + ASSERT_EQUALS(true, tok2->link() == tok1); + } + { // #10615 const char code[] = "struct A : public B<__is_constructible()>{};\n";