TemplateSimplifier: One more fix for #3130. Restored max recursion count to 100 and improve pattern for reference template instantiations instead.

This commit is contained in:
Daniel Marjamäki 2016-01-30 11:22:44 +01:00
parent f116de678e
commit f3f9ea2d09
3 changed files with 22 additions and 9 deletions

View File

@ -815,9 +815,7 @@ void TemplateSimplifier::expandTemplate(
// copy
tokenlist.addtoken(tok3, tok3->linenr(), tok3->fileIndex());
if (Token::Match(tok3, "%type% <")) {
//if (!Token::simpleMatch(tok3, (name + " <").c_str()))
//done = false;
if (Token::Match(tok3, "%type% <") && Token::Match(tok3->next()->findClosingBracket(), ">|>> !!&")) {
templateInstantiations.push_back(tokenlist.back());
}
@ -1268,7 +1266,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
amountOftemplateInstantiations = templateInstantiations.size();
simplifyCalculations(tokenlist.front());
++recursiveCount;
if (recursiveCount > 1) {
if (recursiveCount > 100) {
// bail out..
break;
}

View File

@ -875,7 +875,7 @@ private:
}
void garbageCode104() { // #6847
ASSERT_THROW(checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }"), InternalError);
checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }");
}
void garbageCode105() { // #6859

View File

@ -48,7 +48,7 @@ private:
TEST_CASE(template12);
TEST_CASE(template13);
TEST_CASE(template14);
TEST_CASE(template15);
TEST_CASE(template15); // recursive templates
TEST_CASE(template16);
TEST_CASE(template17);
TEST_CASE(template18);
@ -416,7 +416,7 @@ private:
ASSERT_EQUALS(expected, tok(code));
}
void template15() {
void template15() { // recursive templates #3130 etc
const char code[] = "template <unsigned int i> void a()\n"
"{\n"
" a<i-1>();\n"
@ -436,9 +436,24 @@ private:
"int main ( ) "
"{ a<2> ( ) ; return 0 ; } "
"void a<2> ( ) { a<1> ( ) ; } "
"void a<1> ( ) { a < 0 > ( ) ; }";
"void a<1> ( ) { a<0> ( ) ; }";
ASSERT_EQUALS(expected, tok(code));
// #3130
const char code2[] = "template <int n> struct vec {\n"
" vec() {}\n"
" vec(const vec<n-1>& v) {}\n" // <- never used dont instantiate
"};\n"
"\n"
"vec<4> v;";
const char expected2[] = "vec<4> v ; "
"struct vec<4> { "
"vec<4> ( ) { } "
"vec<4> ( const vec < 4 - 1 > & v ) { } "
"} ;";
ASSERT_EQUALS(expected2, tok(code2));
}
void template16() {
@ -1022,7 +1037,7 @@ private:
"{\n"
" enum {value = !type_equal<T, typename Unconst<T>::type>::value };\n"
"};";
const char expected1[]="template < class T > struct type_equal<T,T> { } ; template < class T > struct template_is_const { } ; struct type_equal<T,T> { } ; struct Unconst<constT*const> { } ; struct Unconst<constT&*const> { } ; struct Unconst<constT&><};template<T> { } ; struct Unconst<constT><};template<T> { } ; struct Unconst<T*const> { } ; struct Unconst<constT*const> { } ; struct Unconst<constT&*const> { } ;";
const char expected1[]="template < class T > struct Unconst { } ; template < class T > struct type_equal<T,T> { } ; template < class T > struct template_is_const { } ; struct type_equal<T,T> { } ; struct Unconst<constT*const> { } ; struct Unconst<constT&*const> { } ; struct Unconst<T*const*const> { } ; struct Unconst<T*const> { } ; struct Unconst<T*const> { } ; struct Unconst<T*const> { } ; struct Unconst<constT&><};template<T> { } ; struct Unconst<constT><};template<T> { } ;";
ASSERT_EQUALS(expected1, tok(code1));
}