Fixed #8725 (Template out of line function return type missing when instantiated.) (#1360)

This commit is contained in:
IOBYTE 2018-09-02 02:35:05 -04:00 committed by Daniel Marjamäki
parent 8353f94b93
commit 341dee4a07
2 changed files with 34 additions and 4 deletions

View File

@ -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();

View File

@ -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 <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -949,11 +950,11 @@ private:
"template void Fred<float> :: f ( ) ; "
"template void Fred<int> :: g ( ) ; "
"class Fred<float> { void f ( ) ; void g ( ) ; } ; "
"Fred<float> :: f ( ) { } "
"Fred<float> :: g ( ) { } "
"void Fred<float> :: f ( ) { } "
"void Fred<float> :: g ( ) { } "
"class Fred<int> { void f ( ) ; void g ( ) ; } ; "
"Fred<int> :: f ( ) { } "
"Fred<int> :: g ( ) { }";
"void Fred<int> :: f ( ) { } "
"void Fred<int> :: g ( ) { }";
ASSERT_EQUALS(expected, tok(code));
}
@ -1192,6 +1193,24 @@ private:
tok(code); // don't crash
}
void template66() { // #8725
const char code[] = "template <class T> struct Fred {\n"
" const int ** foo();\n"
"};\n"
"template <class T> const int ** Fred<T>::foo() { return nullptr; }\n"
"Fred<int> fred;";
const char exp [] = "Fred<int> fred ; struct Fred<int> { "
"const int * * foo ( ) ; "
"} ; "
"const int * * Fred<int> :: foo ( ) { return nullptr ; }";
const char curr[] = "template < class T > const int * * Fred < T > :: foo ( ) { return nullptr ; } "
"Fred<int> fred ; struct Fred<int> { "
"const int * * foo ( ) ; "
"} ; "
"const int * * Fred<int> :: foo ( ) { return nullptr ; }";
TODO_ASSERT_EQUALS(exp, curr, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"