From 3e30fb345ec91e360cce3a25b4c4cf64ad5852af Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Sat, 17 Jan 2009 16:48:11 +0000 Subject: svn merge -r143239:143470 svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_2-branch git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ubuntu/gcc-4_2-branch@143471 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 17 +++++++++ gcc/cp/cp-tree.h | 2 ++ gcc/cp/name-lookup.c | 34 ++++++++++++++++-- gcc/cp/pt.c | 48 ++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 15 ++++++++ gcc/testsuite/g++.dg/lookup/hidden-class12.C | 24 +++++++++++++ gcc/testsuite/g++.dg/lookup/hidden-class13.C | 25 +++++++++++++ gcc/testsuite/g++.dg/lookup/hidden-class14.C | 23 ++++++++++++ gcc/testsuite/g++.dg/lookup/hidden-class15.C | 30 ++++++++++++++++ gcc/testsuite/g++.dg/lookup/hidden-class16.C | 27 ++++++++++++++ gcc/testsuite/g++.dg/template/koenig6.C | 29 +++++++++++++++ gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C | 6 ++-- 13 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class12.C create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class13.C create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class14.C create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class15.C create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class16.C create mode 100644 gcc/testsuite/g++.dg/template/koenig6.C diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 9a6be213020..4f4c252b9d1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090110 +20090117 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 172ccf76b9e..742f90f75dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2009-01-15 Jason Merrill + + PR c++/38850 + * pt.c (tsubst_copy_and_build): Tell finish_call_expr to + accept hidden friends. + +2009-01-12 Dodji Seketeli + + PR c++/36019 + * pt.c (parameter_of_template_p): New function. + * pt.c (get_template_info): Ditto. + * cp-tree.h: Declare those. + * 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. + 2008-11-19 Dodji Seketeli PR c++/37142 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 48d8de8ff20..576fc28d79c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4163,6 +4163,8 @@ extern bool reregister_specialization (tree, tree, tree); extern tree fold_non_dependent_expr (tree); extern bool explicit_class_specialization_p (tree); extern tree outermost_tinst_level (void); +extern tree get_template_info (tree t); +extern bool parameter_of_template_p (tree, tree); /* in repo.c */ extern void init_repo (void); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index f02bf269fad..f990a3bd616 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3850,9 +3850,33 @@ qualified_lookup_using_namespace (tree name, tree scope, 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, @@ -3900,6 +3924,12 @@ 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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 67654df9d91..260229f15ad 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -251,6 +251,25 @@ finish_member_template_decl (tree decl) return error_mark_node; } +/* Return the template info node corresponding to T, whatever T is. */ + +tree +get_template_info (tree t) +{ + tree tinfo = NULL_TREE; + + if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) + tinfo = DECL_TEMPLATE_INFO (t); + + if (!tinfo && TREE_CODE (t) == TYPE_DECL) + t = TREE_TYPE (t); + + if (TAGGED_TYPE_P (t)) + tinfo = TYPE_TEMPLATE_INFO (t); + + return tinfo; +} + /* Returns the template nesting level of the indicated class TYPE. For example, in: @@ -5327,6 +5346,30 @@ outermost_tinst_level (void) return tree_last (current_tinst_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. @@ -9274,9 +9317,12 @@ tsubst_copy_and_build (tree t, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, /*fn_p=*/NULL)); } + /* Pass true for koenig_p so that build_new_function_call will + allow hidden friends found by arg-dependent lookup at template + parsing time. */ return finish_call_expr (function, call_args, /*disallow_virtual=*/qualified_p, - koenig_p); + /*koenig_p*/true); } case COND_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 268fbe0e151..fc8d3f5c080 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2009-01-15 Jason Merrill + + PR c++/38850 + * g++.dg/template/koenig6.C: New test. + +2009-01-12 Dodji Seketeli + + 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. + * gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C: Adjust testcase. + 2008-12-05 Eric Botcazou * gcc.dg/union-5.c: Run only on x86 and x86-64. diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class12.C b/gcc/testsuite/g++.dg/lookup/hidden-class12.C new file mode 100644 index 00000000000..4a3f2d7618b --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class12.C @@ -0,0 +1,24 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/36019 +// { dg-do compile } + +struct F { + static const int x = 0; +}; + +struct A { + template + static int f () + { + return A::x; + } +}; + + +int +main () +{ + int i = A::f (); + return i; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class13.C b/gcc/testsuite/g++.dg/lookup/hidden-class13.C new file mode 100644 index 00000000000..2f685b2cb36 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class13.C @@ -0,0 +1,25 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/36019 +// { dg-do compile } + +struct F { + static const int x = 0; +}; + +struct B { + template + struct C + { + static int f () + { + return B::x; + } + }; +}; + +int +main () +{ + int j = B::C::f (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class14.C b/gcc/testsuite/g++.dg/lookup/hidden-class14.C new file mode 100644 index 00000000000..99bd6731b1b --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class14.C @@ -0,0 +1,23 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/36019 +// { dg-do compile } + +struct F { + static const int x = 0; + typedef int A; +}; + +struct A { + template + struct G : public F + { + static const A i = 0; + }; +}; + +int +main () +{ + return A::G::i ; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class15.C b/gcc/testsuite/g++.dg/lookup/hidden-class15.C new file mode 100644 index 00000000000..b0ed660a6a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class15.C @@ -0,0 +1,30 @@ +// Contributed by Dodji Seketeli +// 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 + struct C + { + static int f () + { + return A::x; // { dg-error "'x' is not a member of 'F'" } + } + }; +}; + +int +main () +{ + int j = B::C::f (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class16.C b/gcc/testsuite/g++.dg/lookup/hidden-class16.C new file mode 100644 index 00000000000..25cc4029408 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class16.C @@ -0,0 +1,27 @@ +// Contributed by Dodji Seketeli +// 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 + static int f () + { + return A::x; // { dg-error "'x' is not a member of 'F'" } + } +}; + +int +main () +{ + int j = B::f (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/koenig6.C b/gcc/testsuite/g++.dg/template/koenig6.C new file mode 100644 index 00000000000..8f93a653a7b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig6.C @@ -0,0 +1,29 @@ +// PR c++/38850 + +template +class Vector2 { + private: + VType c_[2]; + public: + typedef Vector2 Self; + + Vector2(const VType x, const VType y) { + c_[0] = x; + c_[1] = y; + } + + friend inline Self Max(const Self &v1, const Self &v2) { + return Self(v1.c_[0], v1.c_[1]); + } +}; + +template +Vector2 foo(T x) { + Vector2 y(0,0); + return Max(y, y); +} + +int main() { + foo(3); + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C index 73b99659e12..791850366df 100644 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C +++ b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C @@ -83,7 +83,7 @@ public: template struct Xfour {// { dg-error "" } .* int T10; // { dg-error "" } .* void f(){ - char T10; + char T10; // { dg-error "declaration of 'char T10'" } } }; @@ -126,8 +126,8 @@ public: template friend bool foo(T161 u) { - Xseven obj; // { dg-error "" } .* - return (obj.inst == u.inst); // { dg-error "" } .* + Xseven obj; + return (obj.inst == u.inst); } }; -- cgit v1.2.3