diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2ab3281c4..22207ad78 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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; } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index d7ca9d6ea..145dc2e20 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -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 diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 449f2d21f..071410764 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -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 void a()\n" "{\n" " a();\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 struct vec {\n" + " vec() {}\n" + " vec(const vec& 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::type>::value };\n" "};"; - const char expected1[]="template < class T > struct type_equal { } ; template < class T > struct template_is_const { } ; struct type_equal { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst<};template { } ; struct Unconst<};template { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ;"; + const char expected1[]="template < class T > struct Unconst { } ; template < class T > struct type_equal { } ; template < class T > struct template_is_const { } ; struct type_equal { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst { } ; struct Unconst<};template { } ; struct Unconst<};template { } ;"; ASSERT_EQUALS(expected1, tok(code1)); }