diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 71d82cad8..a501b7623 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1031,9 +1031,11 @@ void TemplateSimplifier::expandTemplate( instantiateMatch(tok3, typeParametersInDeclaration.size(), ":: ~| %name% (")) { // there must be template.. bool istemplate = false; + const Token * tok5 = nullptr; // start of function return type for (const Token *prev = tok3; prev && !Token::Match(prev, "[;{}]"); prev = prev->previous()) { if (prev->str() == "template") { istemplate = true; + tok5 = prev; break; } } @@ -1045,6 +1047,15 @@ void TemplateSimplifier::expandTemplate( tok4 = tok4->next(); if (!Tokenizer::isFunctionHead(tok4, ":{", true)) continue; + // find function return type start + tok5 = tok5->next()->findClosingBracket(); + if (tok5) + tok5 = tok5->next(); + // copy return type + while (tok5 && tok5 != tok3) { + mTokenList.addtoken(tok5, tok5->linenr(), tok5->fileIndex()); + tok5 = tok5->next(); + } mTokenList.addtoken(newName, tok3->linenr(), tok3->fileIndex()); while (tok3 && tok3->str() != "::") tok3 = tok3->next(); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 8757f7218..c8217cc74 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -103,6 +103,7 @@ private: TEST_CASE(template63); // #8576 - qualified type TEST_CASE(template64); // #8683 TEST_CASE(template65); // #8321 + TEST_CASE(template66); // #8725 TEST_CASE(template_specialization_1); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) @@ -949,11 +950,11 @@ private: "template void Fred :: f ( ) ; " "template void Fred :: g ( ) ; " "class Fred { void f ( ) ; void g ( ) ; } ; " - "Fred :: f ( ) { } " - "Fred :: g ( ) { } " + "void Fred :: f ( ) { } " + "void Fred :: g ( ) { } " "class Fred { void f ( ) ; void g ( ) ; } ; " - "Fred :: f ( ) { } " - "Fred :: g ( ) { }"; + "void Fred :: f ( ) { } " + "void Fred :: g ( ) { }"; ASSERT_EQUALS(expected, tok(code)); } @@ -1192,6 +1193,24 @@ private: tok(code); // don't crash } + void template66() { // #8725 + const char code[] = "template struct Fred {\n" + " const int ** foo();\n" + "};\n" + "template const int ** Fred::foo() { return nullptr; }\n" + "Fred fred;"; + const char exp [] = "Fred fred ; struct Fred { " + "const int * * foo ( ) ; " + "} ; " + "const int * * Fred :: foo ( ) { return nullptr ; }"; + const char curr[] = "template < class T > const int * * Fred < T > :: foo ( ) { return nullptr ; } " + "Fred fred ; struct Fred { " + "const int * * foo ( ) ; " + "} ; " + "const int * * Fred :: foo ( ) { return nullptr ; }"; + TODO_ASSERT_EQUALS(exp, curr, tok(code)); + } + void template_specialization_1() { // #7868 - template specialization template struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"