+2009-01-12 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36019
+ * pt.c (parameter_of_template_p): New function.
+ * cp-tree.h: Declare it.
+ * name-lookup.c (binding_to_template_parms_of_scope_p): New
+ function.
+ (outer_binding): Take template parameters in account when looking for
+ a name binding.
+
2009-01-12 Jason Merrill <jason@redhat.com>
PR c++/31488
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
extern struct tinst_level *outermost_tinst_level(void);
+extern bool parameter_of_template_p (tree, tree);
/* in repo.c */
extern void init_repo (void);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
+/* Subroutine of outer_binding.
+ Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
+ FALSE otherwise. */
+
+static bool
+binding_to_template_parms_of_scope_p (cxx_binding *binding,
+ cxx_scope *scope)
+{
+ tree binding_value;
+
+ if (!binding || !scope)
+ return false;
+
+ binding_value = binding->value ? binding->value : binding->type;
+
+ return (scope
+ && scope->this_entity
+ && get_template_info (scope->this_entity)
+ && parameter_of_template_p (binding_value,
+ TI_TEMPLATE (get_template_info \
+ (scope->this_entity))));
+}
+
/* Return the innermost non-namespace binding for NAME from a scope
- containing BINDING, or, if BINDING is NULL, the current scope. If
- CLASS_P is false, then class bindings are ignored. */
+ containing BINDING, or, if BINDING is NULL, the current scope.
+ Please note that for a given template, the template parameters are
+ considered to be in the scope containing the current scope.
+ If CLASS_P is false, then class bindings are ignored. */
cxx_binding *
outer_binding (tree name,
return class_binding;
}
}
+ /* If SCOPE is a template and if NAME binds to one of its template parameters
+ return the binding, otherwise we might miss it. */
+ if (outer_scope && outer_scope->kind == sk_template_parms
+ && binding_to_template_parms_of_scope_p (outer, scope))
+ return outer;
+
scope = scope->level_chain;
}
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)
+ if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i)))
+ return true;
+
+ return false;
+}
+
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
vector of template arguments, as for tsubst.
+2009-01-12 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36019
+ * g++.dg/lookup/hidden-class12.C: New test.
+ * g++.dg/lookup/hidden-class13.C: New test.
+ * g++.dg/lookup/hidden-class14.C: New test.
+ * g++.dg/lookup/hidden-class15.C: New test.
+ * g++.dg/lookup/hidden-class16.C: New test.
+
2009-01-12 Mark Mitchell <mark@codesourcery.com>
* gcc.dg/struct/wo_prof_single_str_global.c: Mask return value.
--- /dev/null
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+};
+
+struct A {
+ template <typename A>
+ static int f ()
+ {
+ return A::x;
+ }
+};
+
+
+int
+main ()
+{
+ int i = A::f<F> ();
+ return i;
+}
+
--- /dev/null
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+};
+
+struct B {
+ template <typename B>
+ struct C
+ {
+ static int f ()
+ {
+ return B::x;
+ }
+ };
+};
+
+int
+main ()
+{
+ int j = B::C<F>::f ();
+ return 0;
+}
--- /dev/null
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+ typedef int A;
+};
+
+struct A {
+ template <typename A>
+ struct G : public F
+ {
+ static const A i = 0;
+ };
+};
+
+int
+main ()
+{
+ return A::G<F>::i ;
+}
+
--- /dev/null
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int y = 0;
+};
+
+struct A {
+ static const int x = 0;
+};
+
+struct B : public A {
+ template <typename A>
+ struct C
+ {
+ static int f ()
+ {
+ return A::x; // { dg-error "'x' is not a member of 'F'" }
+ }
+ };
+};
+
+int
+main ()
+{
+ int j = B::C<F>::f ();
+ return 0;
+}
+
--- /dev/null
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int y = 0;
+};
+
+struct A {
+ static const int x = 0;
+};
+
+struct B : public A {
+ template <typename A>
+ static int f ()
+ {
+ return A::x; // { dg-error "'x' is not a member of 'F'" }
+ }
+};
+
+int
+main ()
+{
+ int j = B::f<F> ();
+ return 0;
+}
+