Fixed #9287 and #9288 (Syntax error on valid C++ code) (#2104)

This commit is contained in:
IOBYTE 2019-08-20 14:25:18 -04:00 committed by Daniel Marjamäki
parent a2a874dbd5
commit 4b231c53a4
2 changed files with 47 additions and 1 deletions

View File

@ -3476,6 +3476,8 @@ void Tokenizer::setVarIdPass1()
continue;
if (tok->next() && tok->next()->str() == "::")
continue;
if (Token::simpleMatch(tok->tokAt(-2), ":: template"))
continue;
}
// function declaration inside executable scope? Function declaration is of form: type name "(" args ")"
@ -3943,7 +3945,7 @@ void Tokenizer::createLinks2()
while (!type.empty() && type.top()->str() == "<") {
const Token* end = type.top()->findClosingBracket();
if (Token::Match(end, "> %comp%|;|.|="))
if (Token::Match(end, "> %comp%|;|.|=|{"))
break;
// Variable declaration
if (Token::Match(end, "> %var% ;") && (type.top()->tokAt(-2) == nullptr || Token::Match(type.top()->tokAt(-2), ";|}|{")))

View File

@ -173,6 +173,8 @@ private:
TEST_CASE(template133);
TEST_CASE(template134);
TEST_CASE(template135);
TEST_CASE(template136); // #9287
TEST_CASE(template137); // #9288
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)
@ -3230,6 +3232,48 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template136() { // #9287
const char code[] = "namespace a {\n"
"template <typename> struct b;\n"
"template <int> struct c;\n"
"template <typename> struct d;\n"
"template <typename> struct f;\n"
"template <typename> struct g;\n"
"template <typename h>\n"
"struct i : c<b<f<typename h ::j>>::k && b<g<typename h ::j>>::k> {};\n"
"}\n"
"namespace hana = a;\n"
"using e = int;\n"
"void l(hana::d<hana::i<e>>);";
const char exp[] = "namespace a { "
"template < typename > struct b ; "
"template < int > struct c ; "
"template < typename > struct d ; "
"template < typename > struct f ; "
"template < typename > struct g ; "
"struct i<int> ; "
"} "
"void l ( a :: d < a :: i<int> > ) ; "
"struct a :: i<int> : c < b < f < int :: j > > :: k && b < g < int :: j > > :: k > { } ;";
ASSERT_EQUALS(exp, tok(code));
}
void template137() { // #9288
const char code[] = "template <bool> struct a;\n"
"template <bool b, class> using c = typename a<b>::d;\n"
"template <class, template <class> class, class> struct e;\n"
"template <class f, class g, class... h>\n"
"using i = typename e<f, g::template fn, h...>::d;\n"
"template <class... j> struct k : c<sizeof...(j), int>::template fn<j...> {};";
const char exp[] = "template < bool > struct a ; "
"template < bool b , class > using c = typename a < b > :: d ; "
"template < class , template < class > class , class > struct e ; "
"template < class f , class g , class . . . h > "
"using i = typename e < f , g :: template fn , h . . . > :: d ; "
"template < class . . . j > struct k : c < sizeof . . . ( j ) , int > :: template fn < j . . . > { } ;";
ASSERT_EQUALS(exp, 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"