From bf85767829b959863a1fc82d060177275b784653 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Tue, 26 Feb 2019 00:41:04 -0500 Subject: [PATCH] =?UTF-8?q?template=20simplifier:=20make=20sure=20all=20in?= =?UTF-8?q?stantiations=20are=20found=20and=20expan=E2=80=A6=20(#1696)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * template simplifier: make sure all instantiations are found and expanded in #5097 * template simplifier: check output on another test * template simplifier: add output to another test --- lib/templatesimplifier.cpp | 2 +- test/testsimplifytemplate.cpp | 98 +++++++++++++++++++++++++++++------ 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index e4eec3f6a..8ad583207 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -696,7 +696,7 @@ void TemplateSimplifier::getTemplateInstantiations() else if (!isUsing && tok2 && tok2->str() == ";") tok = const_cast(tok2); } - } else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|& %name% ::|<|(") || + } else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|< %name% ::|<|(") || Token::Match(tok->previous(), "%type% %name% ::|<") || Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) { std::string scopeName = getScopeName(scopeList); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index be559d001..6cc6ba966 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -1010,16 +1010,54 @@ private: } void template43() { // #5097 - Assert due to '>>' in 'B>' not being treated as end of template instantation - const char code[] = "template struct C { };" - "template struct D { static int f() { return C::f(); } };" - "template inline int f2() { return D::f(); }" - "template int f1(int x, T *) { int id = f2(); return id; }" - "template <> struct C < B < A >> {" - " static int f() {" - " return f1 < B < A >> (0, reinterpret_cast< B *>(E::Int(-1)));" - " }" - "};"; - tok(code); // Don't assert + const char code[] = "template struct E { typedef int Int; };\n" + "template struct C { };\n" + "template struct D { static int f() { return C::f(); } };\n" + "template inline int f2() { return D::f(); }\n" + "template int f1 (int x, T *) { int id = f2(); return id; }\n" + "template struct B { void f3(B & other) { } };\n" + "struct A { };\n" + "template <> struct C> {\n" + " static int f() { return f1>(0, reinterpret_cast*>(E::Int(-1))); }\n" + "};\n" + "int main(void) {\n" + " C ca;\n" + " return 0;\n" + "}"; + const char expected[] = "struct E ; " + "struct C ; " + "struct D> ; " + "int f2> ( ) ; " + "int f1> ( int x , B * ) ; " + "struct B ; " + "struct A { } ; " + "struct C> { " + "static int f ( ) { " + "return f1> ( 0 , reinterpret_cast < B * > ( E :: Int ( -1 ) ) ) ; " + "} " + "} ; " + "int main ( ) { " + "C ca ; " + "return 0 ; " + "} " + "struct B { " + "void f3 ( B & other ) { } " + "} ; " + "int f1> ( int x , B * ) { " + "int id ; id = f2> ( ) ; " + "return id ; " + "} " + "int f2> ( ) { " + "return D> :: f ( ) ; " + "} " + "struct D> { " + "static int f ( ) { " + "return C> :: f ( ) ; " + "} " + "} ; " + "struct C { } ; struct E { " + "} ;"; + ASSERT_EQUALS(expected, tok(code, false)); } void template44() { // #5297 @@ -1249,12 +1287,19 @@ private: } void template56() { // #7117 - tok("template struct Foo { " - " std::array mfoo; " - "}; " - "void foo() { " - " Foo myFoo; " - "}", /*simplify=*/true, /*debugwarnings=*/true); + const char code[] = "template struct Foo { " + " std::array mfoo; " + "}; " + "void foo() { " + " Foo myFoo; " + "}"; + const char expected[] = "struct Foo ; " + "void foo ( ) { " + "Foo myFoo ; " + "} struct Foo { " + "std :: array < int , true ? 1 : 2 > mfoo ; " + "} ;"; + ASSERT_EQUALS(expected, tok(code, false, true)); ASSERT_EQUALS("", errout.str()); } @@ -1389,7 +1434,26 @@ private: " t_func<1>();\n" "}\n" "};"; - tok(code); // don't crash + const char exp [] = "bool foo ( ) ; " + "struct A { " + "void t_func<0> ( ) ; " + "void t_func<1> ( ) ; " + "void t_caller ( ) " + "{ " + "t_func<0> ( ) ; " + "t_func<1> ( ) ; " + "} " + "} ; " + "void A :: t_func<0> ( ) " + "{ " + "if ( 0 || foo ( ) ) { ; } " + "} " + "void A :: t_func<1> ( ) " + "{ " + "if ( 1 ) { ; } " + "} " + "bool foo ( ) { return true ; }"; + ASSERT_EQUALS(exp, tok(code, false)); } void template65() { // #8321 (crash)