fix #9886 (Hang in TemplateSimplifier (gcc/gcc/testsuite/g++.dg/cpp0x/decltype34.C))

This commit is contained in:
Robert Reif 2020-09-10 14:47:59 -04:00
parent 6c53cdd6f9
commit a52ce7379a
2 changed files with 20 additions and 1 deletions

View File

@ -1127,7 +1127,7 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
(from->strAt(1) == ">" || (from->previous()->isName() &&
typeParameterNames.find(from->strAt(-1)) == typeParameterNames.end())))
++indentlevel;
else if (from->str() == ">" && (links.empty() || links.top()->str() == "<"))
else if (from->str() == ">" && (links.empty() || links.top()->str() == "<" || indentlevel))
--indentlevel;
auto entry = typeParameterNames.find(from->str());
if (entry != typeParameterNames.end() && entry->second < instantiationArgs.size()) {

View File

@ -198,6 +198,7 @@ private:
TEST_CASE(template156);
TEST_CASE(template157); // #9854
TEST_CASE(template158); // daca crash
TEST_CASE(template159); // #9886
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)
@ -4018,6 +4019,24 @@ private:
tok(code); // don't crash
}
void template159() { // #9886
const char code[] = "struct impl { template <class T> static T create(); };\n"
"template<class T, class U, class = decltype(impl::create<T>()->impl::create<U>())>\n"
"struct tester{};\n"
"tester<impl*, int> ti;\n"
"template<class T, class U, class = decltype(impl::create<T>()->impl::create<U>())>\n"
"int test() { return 0; }\n"
"int i = test<impl*, int>();";
const char exp[] = "struct impl { template < class T > static T create ( ) ; } ; "
"struct tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ; "
"tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ti ; "
"int test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) ; "
"int i ; i = test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) ; "
"int test<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> ( ) { return 0 ; } "
"struct tester<impl*,int,decltype(impl::create<impl*>().impl::create<int>())> { } ;";
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"