From 1428759479df07218ea9b6ef4a6681f4186d6582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 17 Dec 2017 15:53:05 +0100 Subject: [PATCH] Fixed #8297 (Tokenizer:createLinks: 'X()') --- lib/tokenize.cpp | 25 +++++++++++++++++++++++++ test/testtokenize.cpp | 22 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1f20dea4c..978b7dc08 100755 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3235,6 +3235,31 @@ void Tokenizer::createLinks2() } else if (!templateToken && !isStruct && Token::Match(token, "%oror%|&&|;")) { if (Token::Match(token, "&& [,>]")) continue; + // If there is some such code: A.. + // Then this is probably a template instantiation if either "B" or "C" has comparisons + if (token->tokType() == Token::eLogicalOp && !type.empty() && type.top()->str() == "<") { + const Token *prev = token->previous(); + while (Token::Match(prev, "%name%|%num%|%str%|%cop%|)|]")) { + if (prev->str() == ")" || prev->str() == "]") + prev = prev->link(); + else if (prev->tokType() == Token::eLogicalOp || prev->isComparisonOp()) + break; + prev = prev->previous(); + } + if (prev && prev != type.top() && prev->isComparisonOp()) + continue; + const Token *next = token->next(); + while (Token::Match(next, "%name%|%num%|%str%|%cop%|(|[")) { + if (next->str() == "(" || next->str() == "[") + next = next->link(); + else if (next->tokType() == Token::eLogicalOp || next->isComparisonOp()) + break; + next = next->next(); + } + if (next && next != type.top() && next->isComparisonOp() && next->str() != ">") + continue; + } + while (!type.empty() && type.top()->str() == "<") type.pop(); } else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId()) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e9ac5ca48..a668c07f0 100755 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4522,6 +4522,28 @@ private: ASSERT_EQUALS(true, tok->linkAt(3) == nullptr); } + { + // template + const char code[] = "a d;"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + const Token *tok = tokenizer.tokens(); + ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7)); + } + + { + // template + const char code[] = "a d;"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + const Token *tok = tokenizer.tokens(); + ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7)); + } + { const char code[] = "template < f = b || c > struct S;"; errout.str("");