From e61e1cb13da142eaf90d5e6ba1451b23281d8ce9 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Wed, 14 May 2014 22:27:31 +0200 Subject: [PATCH] Ticket #5786: Properly handle cv-qualified member pointers as template parameter. --- lib/templatesimplifier.cpp | 9 ++++++--- test/testtokenize.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 03318aed9..3f06253f3 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -228,8 +228,8 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) unsigned int level = 0; while (tok) { - // skip const - if (tok->str() == "const") + // skip const/volatile + if (Token::Match(tok, "const|volatile")) tok = tok->next(); // skip struct/union @@ -278,8 +278,11 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) return 0; // Function pointer or prototype.. - while (tok && (tok->str() == "(" || tok->str() == "[")) + while (tok && (tok->str() == "(" || tok->str() == "[")) { tok = tok->link()->next(); + while (tok && Token::Match(tok, "const|volatile")) // Ticket #5786: Skip function cv-qualifiers + tok = tok->next(); + } if (!tok) return 0; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 73fc1d380..d994348ef 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -420,6 +420,7 @@ private: TEST_CASE(syntax_error_templates_1); TEST_CASE(syntax_error_templates_2); TEST_CASE(syntax_error_templates_3); // Ticket #5605, #5759, #5762, #5774 + TEST_CASE(template_member_ptr); // Ticket #5786 - crash upon valid code TEST_CASE(removeKeywords); @@ -6540,6 +6541,33 @@ private: "A a;"); } + void template_member_ptr() { // Ticket #5786 + tokenizeAndStringify("struct A {}; " + "struct B { " + "template struct BB {}; " + "template static bool foo(int) { return true; } " + "void bar() { bool b = foo(0); }" + "};"); + tokenizeAndStringify("struct A {}; " + "struct B { " + "template struct BB {}; " + "template static bool foo(int) { return true; } " + "void bar() { bool b = foo(0); }" + "};"); + tokenizeAndStringify("struct A {}; " + "struct B { " + "template struct BB {}; " + "template static bool foo(int) { return true; } " + "void bar() { bool b = foo(0); }" + "};"); + tokenizeAndStringify("struct A {}; " + "struct B { " + "template struct BB {}; " + "template static bool foo(int) { return true; } " + "void bar() { bool b = foo(0); }" + "};"); + } + void removeKeywords() { const char code[] = "if (__builtin_expect(!!(x), 1));";