Fix #9178 example with instantiation (#2059)

This commit is contained in:
IOBYTE 2019-08-02 01:53:39 -04:00 committed by Daniel Marjamäki
parent 5390588cda
commit 0d1685cd29
2 changed files with 28 additions and 7 deletions

View File

@ -1627,7 +1627,9 @@ void TemplateSimplifier::expandTemplate(
// skip scope
while (start->strAt(1) != templateDeclarationNameToken->str())
start = start->next();
} else if (start->str() == templateDeclarationNameToken->str()) {
} else if (start->str() == templateDeclarationNameToken->str() &&
!(templateDeclaration.isFunction() && templateDeclaration.scope.empty() &&
(start->strAt(-1) == "." || Token::simpleMatch(start->tokAt(-2), ". template")))) {
if (start->strAt(1) != "<" || Token::Match(start, newName.c_str()) || !inAssignment) {
dst->insertToken(newName, "", true);
if (start->strAt(1) == "<")
@ -2801,7 +2803,9 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
}
// A global function can't be called through a pointer.
if (templateDeclaration.isFunction() && templateDeclaration.scope.empty() && instantiation.token->strAt(-1) == ".")
if (templateDeclaration.isFunction() && templateDeclaration.scope.empty() &&
(instantiation.token->strAt(-1) == "." ||
Token::simpleMatch(instantiation.token->tokAt(-2), ". template")))
continue;
if (!matchSpecialization(templateDeclaration.nameToken, instantiation.token, specializations))

View File

@ -2774,11 +2774,28 @@ private:
}
void template116() { // #9178
const char code[] = "template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>);\n"
"template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>){}";
const char exp[] = "template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) ; "
"template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) { }";
ASSERT_EQUALS(exp, tok(code));
{
const char code[] = "template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>);\n"
"template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>){}";
const char exp[] = "template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) ; "
"template < class , class a > auto b ( ) . decltype ( a { } . template b < void ( int , int ) > ) { }";
ASSERT_EQUALS(exp, tok(code));
}
{
const char code[] = "template <class, class a>\n"
"auto b() -> decltype(a{}.template b<void(int, int)>()) {}\n"
"struct c {\n"
" template <class> void b();\n"
"};\n"
"void d() { b<c, c>(); }";
const char exp[] = "auto b<c,c> ( ) . decltype ( c { } . template b < void ( int , int ) > ( ) ) ; "
"struct c { "
"template < class > void b ( ) ; "
"} ; "
"void d ( ) { b<c,c> ( ) ; } "
"auto b<c,c> ( ) . decltype ( c { } . template b < void ( int , int ) > ( ) ) { }";
ASSERT_EQUALS(exp, tok(code));
}
}
void template117() {