@@ -289,6 +289,7 @@ class TestSimplifyTemplate : public TestFixture {
289289 TEST_CASE (templateTypeDeduction8); // deduction from expressions
290290 TEST_CASE (templateTypeDeduction9); // multiple parameters, scopes, bailouts
291291 TEST_CASE (templateTypeDeduction10); // parameter visibility: init list, const method
292+ TEST_CASE (templateTypeDeduction11); // unqualified lookup: enclosing scopes, shadowing
292293
293294 TEST_CASE (simplifyTemplateArgs1);
294295 TEST_CASE (simplifyTemplateArgs2);
@@ -6536,6 +6537,76 @@ class TestSimplifyTemplate : public TestFixture {
65366537 ASSERT_EQUALS (" " , errout_str ());
65376538 }
65386539
6540+ void templateTypeDeduction11 () { // unqualified lookup: enclosing scopes, shadowing
6541+ {
6542+ // global function template called from a class scope
6543+ const char code[] = " template<typename T> void f(T n) { (void)n; }\n "
6544+ " struct A {\n "
6545+ " int m;\n "
6546+ " A(long n) : m(0) { f(n); }\n "
6547+ " void g(float v) const { f(v); }\n "
6548+ " };" ;
6549+ const char exp[] = " void f<long> ( long n ) ; "
6550+ " void f<float> ( float n ) ; "
6551+ " struct A { "
6552+ " int m ; "
6553+ " A ( long n ) : m ( 0 ) { f<long> ( n ) ; } "
6554+ " void g ( float v ) const { f<float> ( v ) ; } "
6555+ " } ; "
6556+ " void f<long> ( long n ) { ( void ) n ; } "
6557+ " void f<float> ( float n ) { ( void ) n ; }" ;
6558+ ASSERT_EQUALS (exp, tok (code));
6559+ }
6560+ {
6561+ // global function template called from a class nested in a namespace
6562+ const char code[] = " template<typename T> T twice(T v) { return v + v; }\n "
6563+ " namespace N {\n "
6564+ " struct Inner {\n "
6565+ " long go(int a) { return twice(a); }\n "
6566+ " };\n "
6567+ " }" ;
6568+ const char exp[] = " int twice<int> ( int v ) ; "
6569+ " namespace N { "
6570+ " struct Inner { "
6571+ " long go ( int a ) { return twice<int> ( a ) ; } "
6572+ " } ; "
6573+ " } "
6574+ " int twice<int> ( int v ) { return v + v ; }" ;
6575+ ASSERT_EQUALS (exp, tok (code));
6576+ }
6577+ {
6578+ // a variable with the same name hides the function template
6579+ const char code[] = " template<typename T> void call(T v) { (void)v; }\n "
6580+ " struct Functor { void operator()(int) const {} };\n "
6581+ " void g() {\n "
6582+ " Functor call;\n "
6583+ " call(5);\n "
6584+ " }" ;
6585+ const char exp[] = " template < typename T > void call ( T v ) { ( void ) v ; } "
6586+ " struct Functor { void operator() ( int ) const { } } ; "
6587+ " void g ( ) { "
6588+ " Functor call ; "
6589+ " call . operator() ( 5 ) ; "
6590+ " }" ;
6591+ ASSERT_EQUALS (exp, tok (code));
6592+ }
6593+ {
6594+ // a member function template shadows a global function template
6595+ const char code[] = " template<typename T> void dup(T t) { (void)t; }\n "
6596+ " struct B {\n "
6597+ " template<typename T> void dup(T t) { (void)t; }\n "
6598+ " void m() { dup(1L); }\n "
6599+ " };" ;
6600+ const char exp[] = " template < typename T > void dup ( T t ) { ( void ) t ; } "
6601+ " struct B { "
6602+ " void dup<long> ( long t ) ; "
6603+ " void m ( ) { dup<long> ( 1L ) ; } "
6604+ " } ; "
6605+ " void B :: dup<long> ( long t ) { ( void ) t ; }" ;
6606+ ASSERT_EQUALS (exp, tok (code));
6607+ }
6608+ }
6609+
65396610 void simplifyTemplateArgs1 () {
65406611 ASSERT_EQUALS (" foo<2> = 2 ; foo<2> ;" , tok (" template<int N> foo = N; foo < ( 2 ) >;" ));
65416612 ASSERT_EQUALS (" foo<2> = 2 ; foo<2> ;" , tok (" template<int N> foo = N; foo < 1 + 1 >;" ));
0 commit comments