From 221873e69f4d1c16ae4d14d05e55610f107fa620 Mon Sep 17 00:00:00 2001 From: gerboengels Date: Sun, 16 Oct 2022 19:33:44 +0200 Subject: [PATCH] Fix #11319 (#4549) In this example: ``` //template T> // <= works template T> // <= didn't work void f() {} ``` the changed line used to match to `< same_as <`, therefore skip creating links. The `%op% %name% <` already feels a bit like a workaround. So adding the condition that $op$ shouldn't be a comparison operator, but part of the template, seemed reasonable to me Co-authored-by: Gerbo Engels --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7985f45c9..e908f5bda 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4702,7 +4702,7 @@ void Tokenizer::createLinks2() } else { type.pop(); if (Token::Match(token, "> %name%") && !token->next()->isKeyword() && - Token::Match(top1->tokAt(-2), "%op% %name% <") && + Token::Match(top1->tokAt(-2), "%op% %name% <") && top1->strAt(-2) != "<" && (templateTokens.empty() || top1 != templateTokens.top())) continue; Token::createMutualLinks(top1, token); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 905743686..035e413c7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3250,6 +3250,20 @@ private: ASSERT(nullptr == Token::findsimplematch(tokenizer.tokens(), "<")->link()); } + { + // #11319 + const char code[] = "using std::same_as;\n" + "template T>\n" + "void f();"; + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "template <"); + const Token *tok2 = Token ::findsimplematch(tokenizer.tokens(), "same_as <"); + ASSERT(tok1->next()->link() == tok1->tokAt(7)); + ASSERT(tok2->next()->link() == tok2->tokAt(3)); + } + { // #9131 - template usage or comparison? const char code[] = "using std::list; list l;";