Hello, In the example of the patch below, the lookup of symbol 'T' yields the template parameter instead of the typedef Base::T. That's because outer_binding considers the template-parameters-scope bindings from Derived<T>::foo even though that template doesn't have it's own template header. outer_binding should first consider the class-scope bindings from Derived<T>::foo.
The patch tightens binding_to_template_parms_of_scope_p to make it only consider template parameters of the scope of a template which has its own template header. Tested on x86_64-unknown-linux-gnu against trunk. -- Dodji >From 48496aa3972649c82bc1c16c59c461102270caad Mon Sep 17 00:00:00 2001 From: Dodji Seketeli <do...@redhat.com> Date: Mon, 7 Mar 2011 16:47:17 +0100 Subject: [PATCH] PR c++/47957 gcc/cp/ * name-lookup.c (binding_to_template_parms_of_scope_p): Only consider scopes of primary template definitions. Adjust comments. gcc/testsuite/ * g++.dg/lookup/template3.C: New test. --- gcc/cp/name-lookup.c | 11 ++++++++- gcc/testsuite/g++.dg/lookup/template3.C | 35 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/template3.C diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 4117202..18e3441 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4205,8 +4205,13 @@ qualified_lookup_using_namespace (tree name, tree scope, } /* Subroutine of outer_binding. - Returns TRUE if BINDING is a binding to a template parameter of SCOPE, - FALSE otherwise. */ + + Returns TRUE if BINDING is a binding to a template parameter of + SCOPE. In that case SCOPE is the scope of a primary template + parameter -- in the sense of G++, i.e, a template that has its own + template header. + + Returns FALSE otherwise. */ static bool binding_to_template_parms_of_scope_p (cxx_binding *binding, @@ -4222,6 +4227,8 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding, return (scope && scope->this_entity && get_template_info (scope->this_entity) + && PRIMARY_TEMPLATE_P (TI_TEMPLATE + (get_template_info (scope->this_entity))) && parameter_of_template_p (binding_value, TI_TEMPLATE (get_template_info \ (scope->this_entity)))); diff --git a/gcc/testsuite/g++.dg/lookup/template3.C b/gcc/testsuite/g++.dg/lookup/template3.C new file mode 100644 index 0000000..e5f6f18 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/template3.C @@ -0,0 +1,35 @@ +// Origin PR c++/47957 +// { dg-do compile } + +struct S +{ + int m; + + S() + : m(0) + { + } +}; + +struct Base +{ + typedef S T; +}; + +template<class T> +struct Derived : public Base +{ + int + foo() + { + T a; // This is Base::T, not the template parameter. + return a.m; + } +}; + +int +main() +{ + Derived<char> d; + return d.foo(); +} -- 1.7.3.4