Fixed #9147(SymbolDatabase bailout: unhandled code) (#1948)

* Fixed #9147(SymbolDatabase bailout: unhandled code)

* add test for #9183
This commit is contained in:
IOBYTE 2019-07-03 02:35:48 -04:00 committed by Daniel Marjamäki
parent f84dcc4738
commit c4933acb5a
3 changed files with 80 additions and 0 deletions

View File

@ -1893,6 +1893,8 @@ bool Tokenizer::simplifyUsing()
if (!endOfTemplateDefinition) {
if (tok->str() == "{")
endOfTemplateDefinition = tok->link();
else if (tok->str() == ";")
endOfTemplateDefinition = tok;
}
if (tok == endOfTemplateDefinition) {
inTemplateDefinition = false;
@ -1997,6 +1999,27 @@ bool Tokenizer::simplifyUsing()
continue;
}
// skip template definitions
if (Token::Match(tok1, "template < !!>")) {
tok1 = tok1->next()->findClosingBracket();
if (tok1) {
Token * tok2 = tok1->next();
while (tok2 && !Token::Match(tok2, ";|{")) {
if (tok2->str() == "<")
tok2 = tok2->findClosingBracket();
else if (Token::Match(tok2, "(|[") && tok2->link())
tok2 = tok2->link();
if (tok2)
tok2 = tok2->next();
}
if (tok2 && tok2->str() == "{")
tok1 = tok2->link();
else if (tok2 && tok2->str() == ";")
tok1 = tok2;
}
continue;
}
if (!usingMatch(nameToken, scope, &tok1, scope1, scopeList1))
continue;

View File

@ -159,6 +159,8 @@ private:
TEST_CASE(template119); // #9186
TEST_CASE(template120);
TEST_CASE(template121); // #9193
TEST_CASE(template122); // #9147
TEST_CASE(template123); // #9183
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)
@ -2860,6 +2862,48 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template122() { // #9147
const char code[] = "template <class...> struct a;\n"
"namespace {\n"
"template <class, class> struct b;\n"
"template <template <class> class c, class... f, template <class...> class d>\n"
"struct b<c<f...>, d<>>;\n"
"}\n"
"void e() { using c = a<>; }";
const char exp[] = "template < class . . . > struct a ; "
"namespace { "
"template < class , class > struct b ; "
"template < template < class > class c , class . . . f , template < class . . . > class d > "
"struct b < c < f . . . > , d < > > ; "
"} "
"void e ( ) { }";
ASSERT_EQUALS(exp, tok(code));
}
void template123() { // #9183
const char code[] = "template <class...> struct a;\n"
"namespace {\n"
"template <class, class, class, class>\n"
"struct b;\n"
"template <template <class> class c, class... d, template <class> class e, class... f>\n"
"struct b<c<d...>, e<f...>>;\n"
"}\n"
"void fn1() {\n"
" using c = a<>;\n"
" using e = a<>;\n"
"}";
const char exp[] = "template < class . . . > struct a ; "
"namespace { "
"template < class , class , class , class > "
"struct b ; "
"template < template < class > class c , class . . . d , template < class > class e , class . . . f > "
"struct b < c < d . . . > , e < f . . . > > ; "
"} "
"void fn1 ( ) { "
"}";
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"

View File

@ -297,6 +297,7 @@ private:
TEST_CASE(symboldatabase75);
TEST_CASE(symboldatabase76); // #9056
TEST_CASE(symboldatabase77); // #8663
TEST_CASE(symboldatabase78); // #9147
TEST_CASE(createSymbolDatabaseFindAllScopes1);
@ -4222,6 +4223,18 @@ private:
ASSERT_EQUALS(2, db->mVariableList.size());
}
void symboldatabase78() { // #9147
GET_SYMBOL_DB("template <class...> struct a;\n"
"namespace {\n"
"template <class, class> struct b;\n"
"template <template <class> class c, class... f, template <class...> class d>\n"
"struct b<c<f...>, d<>>;\n"
"}\n"
"void e() { using c = a<>; }");
ASSERT(db != nullptr);
ASSERT_EQUALS("", errout.str());
}
void createSymbolDatabaseFindAllScopes1() {
GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }");
ASSERT(db->scopeList.size() == 3);