aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2012-03-13 21:25:22 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2012-03-13 22:25:22 +0100
commit74788b800931abc7ab79a06812799862eede96c0 (patch)
tree1846e2e040151c9f4edde0f36e6c882543d14679
parent40703fdf12ebe0a89e104f303906128e3a729279 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c28
-rw-r--r--gcc/cp/pt.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class17.C22
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;
+