template simplifier: make sure all instantiations are found and expan… (#1696)
* 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
This commit is contained in:
parent
3f257d6310
commit
bf85767829
|
@ -696,7 +696,7 @@ void TemplateSimplifier::getTemplateInstantiations()
|
||||||
else if (!isUsing && tok2 && tok2->str() == ";")
|
else if (!isUsing && tok2 && tok2->str() == ";")
|
||||||
tok = const_cast<Token *>(tok2);
|
tok = const_cast<Token *>(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->previous(), "%type% %name% ::|<") ||
|
||||||
Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) {
|
Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) {
|
||||||
std::string scopeName = getScopeName(scopeList);
|
std::string scopeName = getScopeName(scopeList);
|
||||||
|
|
|
@ -1010,16 +1010,54 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void template43() { // #5097 - Assert due to '>>' in 'B<A<C>>' not being treated as end of template instantation
|
void template43() { // #5097 - Assert due to '>>' in 'B<A<C>>' not being treated as end of template instantation
|
||||||
const char code[] = "template <typename T> struct C { };"
|
const char code[] = "template <typename T> struct E { typedef int Int; };\n"
|
||||||
"template <typename T> struct D { static int f() { return C<T>::f(); } };"
|
"template <typename T> struct C { };\n"
|
||||||
"template <typename T> inline int f2() { return D<T>::f(); }"
|
"template <typename T> struct D { static int f() { return C<T>::f(); } };\n"
|
||||||
"template <typename T> int f1(int x, T *) { int id = f2<T>(); return id; }"
|
"template <typename T> inline int f2() { return D<T>::f(); }\n"
|
||||||
"template <> struct C < B < A >> {"
|
"template <typename T> int f1 (int x, T *) { int id = f2<T>(); return id; }\n"
|
||||||
" static int f() {"
|
"template <typename T> struct B { void f3(B<T> & other) { } };\n"
|
||||||
" return f1 < B < A >> (0, reinterpret_cast< B<A> *>(E<void *>::Int(-1)));"
|
"struct A { };\n"
|
||||||
" }"
|
"template <> struct C<B<A>> {\n"
|
||||||
"};";
|
" static int f() { return f1<B<A>>(0, reinterpret_cast<B<A>*>(E<void*>::Int(-1))); }\n"
|
||||||
tok(code); // Don't assert
|
"};\n"
|
||||||
|
"int main(void) {\n"
|
||||||
|
" C<A> ca;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}";
|
||||||
|
const char expected[] = "struct E<void*> ; "
|
||||||
|
"struct C<A> ; "
|
||||||
|
"struct D<B<A>> ; "
|
||||||
|
"int f2<B<A>> ( ) ; "
|
||||||
|
"int f1<B<A>> ( int x , B<A> * ) ; "
|
||||||
|
"struct B<A> ; "
|
||||||
|
"struct A { } ; "
|
||||||
|
"struct C<B<A>> { "
|
||||||
|
"static int f ( ) { "
|
||||||
|
"return f1<B<A>> ( 0 , reinterpret_cast < B<A> * > ( E<void*> :: Int ( -1 ) ) ) ; "
|
||||||
|
"} "
|
||||||
|
"} ; "
|
||||||
|
"int main ( ) { "
|
||||||
|
"C<A> ca ; "
|
||||||
|
"return 0 ; "
|
||||||
|
"} "
|
||||||
|
"struct B<A> { "
|
||||||
|
"void f3 ( B<A> & other ) { } "
|
||||||
|
"} ; "
|
||||||
|
"int f1<B<A>> ( int x , B<A> * ) { "
|
||||||
|
"int id ; id = f2<B<A>> ( ) ; "
|
||||||
|
"return id ; "
|
||||||
|
"} "
|
||||||
|
"int f2<B<A>> ( ) { "
|
||||||
|
"return D<B<A>> :: f ( ) ; "
|
||||||
|
"} "
|
||||||
|
"struct D<B<A>> { "
|
||||||
|
"static int f ( ) { "
|
||||||
|
"return C<B<A>> :: f ( ) ; "
|
||||||
|
"} "
|
||||||
|
"} ; "
|
||||||
|
"struct C<A> { } ; struct E<void*> { "
|
||||||
|
"} ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void template44() { // #5297
|
void template44() { // #5297
|
||||||
|
@ -1249,12 +1287,19 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void template56() { // #7117
|
void template56() { // #7117
|
||||||
tok("template<bool B> struct Foo { "
|
const char code[] = "template<bool B> struct Foo { "
|
||||||
" std::array<int, B ? 1 : 2> mfoo; "
|
" std::array<int, B ? 1 : 2> mfoo; "
|
||||||
"}; "
|
"}; "
|
||||||
"void foo() { "
|
"void foo() { "
|
||||||
" Foo<true> myFoo; "
|
" Foo<true> myFoo; "
|
||||||
"}", /*simplify=*/true, /*debugwarnings=*/true);
|
"}";
|
||||||
|
const char expected[] = "struct Foo<true> ; "
|
||||||
|
"void foo ( ) { "
|
||||||
|
"Foo<true> myFoo ; "
|
||||||
|
"} struct Foo<true> { "
|
||||||
|
"std :: array < int , true ? 1 : 2 > mfoo ; "
|
||||||
|
"} ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code, false, true));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,7 +1434,26 @@ private:
|
||||||
" t_func<1>();\n"
|
" t_func<1>();\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"};";
|
"};";
|
||||||
tok(code); // don't crash
|
const char exp [] = "bool foo<int> ( ) ; "
|
||||||
|
"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<int> ( ) ) { ; } "
|
||||||
|
"} "
|
||||||
|
"void A :: t_func<1> ( ) "
|
||||||
|
"{ "
|
||||||
|
"if ( 1 ) { ; } "
|
||||||
|
"} "
|
||||||
|
"bool foo<int> ( ) { return true ; }";
|
||||||
|
ASSERT_EQUALS(exp, tok(code, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void template65() { // #8321 (crash)
|
void template65() { // #8321 (crash)
|
||||||
|
|
Loading…
Reference in New Issue