diff options
author | Dodji Seketeli <dodji@redhat.com> | 2012-03-13 21:25:22 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2012-03-13 22:25:22 +0100 |
commit | 74788b800931abc7ab79a06812799862eede96c0 (patch) | |
tree | 1846e2e040151c9f4edde0f36e6c882543d14679 | |
parent | 40703fdf12ebe0a89e104f303906128e3a729279 (diff) | |
download | gcc-74788b800931abc7ab79a06812799862eede96c0.zip gcc-74788b800931abc7ab79a06812799862eede96c0.tar.gz gcc-74788b800931abc7ab79a06812799862eede96c0.tar.bz2 |
PR c++/51641 - Lookup finds enclosing class member instead of template parameter
gcc/cp/
PR c++/51641
* cp-tree.h (template_type_parameter_p): Declare new function.
(parameter_of_template_p): Remove
* pt.c (template_type_parameter_p): Define new function.
(parameter_of_template_p): Remove.
* name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely
on parameter_of_template_p anymore. Compare the level of the
template parameter to the depth of the template.
gcc/testsuite/
PR c++/51641
* g++.dg/lookup/hidden-class17.C: New test.
Conflicts:
gcc/cp/pt.c
From-SVN: r185357
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 28 | ||||
-rw-r--r-- | gcc/cp/pt.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/hidden-class17.C | 22 |
6 files changed, 75 insertions, 37 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f04ac60..6ef5545 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2012-01-30 Dodji Seketeli <dodji@redhat.com> + + PR c++/51641 + * cp-tree.h (template_type_parameter_p): Declare new function. + (parameter_of_template_p): Remove + * pt.c (template_type_parameter_p): Define new function. + (parameter_of_template_p): Remove. + * name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely + on parameter_of_template_p anymore. Compare the level of the + template parameter to the depth of the template. + 2011-12-15 Dodji Seketeli <dodji@redhat.com> * call.c (standard_conversion, build_integral_nontype_arg_conv) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 71573ff..d24c596 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5361,10 +5361,10 @@ extern bool explicit_class_specialization_p (tree); extern int push_tinst_level (tree); extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); -extern bool parameter_of_template_p (tree, tree); extern void init_template_processing (void); extern void print_template_statistics (void); bool template_template_parameter_p (const_tree); +bool template_type_parameter_p (const_tree); extern bool primary_template_instantiation_p (const_tree); extern tree get_primary_template_innermost_parameters (const_tree); extern tree get_template_parms_at_level (tree, int); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e85d603..886a7b1 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4466,8 +4466,8 @@ static bool binding_to_template_parms_of_scope_p (cxx_binding *binding, cp_binding_level *scope) { - tree binding_value; - tree tinfo; + tree binding_value, tmpl, tinfo; + int level; if (!binding || !scope || !scope->this_entity) return false; @@ -4475,9 +4475,29 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding, binding_value = binding->value ? binding->value : binding->type; tinfo = get_template_info (scope->this_entity); - return (tinfo + /* BINDING_VALUE must be a template parm. */ + if (binding_value == NULL_TREE + || (!DECL_P (binding_value) + || !DECL_TEMPLATE_PARM_P (binding_value))) + return false; + + /* The level of BINDING_VALUE. */ + level = + template_type_parameter_p (binding_value) + ? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX + (TREE_TYPE (binding_value))) + : TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value)); + + /* The template of the current scope, iff said scope is a primary + template. */ + tmpl = (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) - && parameter_of_template_p (binding_value, TI_TEMPLATE (tinfo))); + ? TI_TEMPLATE (tinfo) + : NULL_TREE); + + /* If the level of the parm BINDING_VALUE equals the depth of TMPL, + then BINDING_VALUE is a parameter of TMPL. */ + return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); } /* Return the innermost non-namespace binding for NAME from a scope diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 54d540d..6dd004e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2869,6 +2869,18 @@ template_template_parameter_p (const_tree parm) return DECL_TEMPLATE_TEMPLATE_PARM_P (parm); } +/* Return true iff PARM is a DECL representing a type template + parameter. */ + +bool +template_type_parameter_p (const_tree parm) +{ + return (parm + && (TREE_CODE (parm) == TYPE_DECL + || TREE_CODE (parm) == TEMPLATE_DECL) + && DECL_TEMPLATE_PARM_P (parm)); +} + /* Return the template parameters of T if T is a primary template instantiation, NULL otherwise. */ @@ -8118,38 +8130,6 @@ outermost_tinst_level (void) return level; } -/* Returns TRUE if PARM is a parameter of the template TEMPL. */ - -bool -parameter_of_template_p (tree parm, tree templ) -{ - tree parms; - int i; - - if (!parm || !templ) - return false; - - gcc_assert (DECL_TEMPLATE_PARM_P (parm)); - gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); - - parms = DECL_TEMPLATE_PARMS (templ); - parms = INNERMOST_TEMPLATE_PARMS (parms); - - for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) - { - tree p = TREE_VALUE (TREE_VEC_ELT (parms, i)); - if (p == error_mark_node) - continue; - - if (parm == p - || (DECL_INITIAL (parm) - && DECL_INITIAL (parm) == DECL_INITIAL (p))) - return true; - } - - return false; -} - /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2824244..bf9503c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-01-30 Dodji Seketeli <dodji@redhat.com> + + PR c++/51641 + * g++.dg/lookup/hidden-class17.C: New test. + 2012-03-13 Jakub Jelinek <jakub@redhat.com> PR c/52577 diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class17.C b/gcc/testsuite/g++.dg/lookup/hidden-class17.C new file mode 100644 index 0000000..3d5ccec --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class17.C @@ -0,0 +1,22 @@ +// Origin PR c++/51641 +// { dg-do compile } + +struct A { + struct B { typedef int X; }; +}; + +template<class B> struct C : A { + B::X q; // Ok: A::B. + struct U { typedef int X; }; + template<class U> + struct D; +}; + +template<class B> +template<class U> +struct C<B>::D { + typename U::X r; // { dg-error "" } +}; + +C<int>::D<double> y; + |