From 8cbd9b03aa5f96e4c5d9c84503fa3fd3270ad49c Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 19 May 2019 03:05:34 -0500 Subject: [PATCH] Fix issue 8890: AST broken calling member function from templated base class (#1836) * Fix issue 8890: AST broken calling member function from templated base class * Format * Check for double bracket * Add test to createLinks2 * Remove extra test * Reduce test case for links --- lib/tokenize.cpp | 4 +++- test/testtokenize.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 541888957..e37c49fc6 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3847,7 +3847,9 @@ void Tokenizer::createLinks2() while (!type.empty() && type.top()->str() == "<") type.pop(); - } else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId()) { + } else if (token->str() == "<" && + ((token->previous() && token->previous()->isName() && !token->previous()->varId()) || + Token::Match(token->next(), ">|>>"))) { type.push(token); if (!templateToken && (token->previous()->str() == "template")) templateToken = token; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 668c41730..db70c90cc 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -455,6 +455,7 @@ private: // The TestGarbage ensures that there are true positives TEST_CASE(findGarbageCode); TEST_CASE(checkEnableIf); + TEST_CASE(checkTemplates); // #9052 TEST_CASE(noCrash1); @@ -4795,6 +4796,18 @@ private: tokenizer.tokenize(istr, "test.cpp"); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "<")->link()); } + + { + // #8890 + const char code[] = "void f() {\n" + " a<> b;\n" + " b.a<>::c();\n" + "}\n"; + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ::")->link()); + } } void simplifyString() { @@ -7583,6 +7596,18 @@ private: } + void checkTemplates() { + ASSERT_NO_THROW(tokenizeAndStringify( + "template struct a {\n" + " void c();\n" + "};\n" + "void f() {\n" + " a<> b;\n" + " b.a<>::c();\n" + "}\n")) + } + + void noCrash1() { ASSERT_NO_THROW(tokenizeAndStringify( "struct A {\n"