From: Kriang Lerdsuwanakij Date: Sun, 2 Nov 2003 14:17:39 +0000 (+0000) Subject: re PR c++/9810 (Using-declaration for template functions does not work) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3dfa3500061aede01f2d1bcf7db0c8ae7531087a;p=platform%2Fupstream%2Fgcc.git re PR c++/9810 (Using-declaration for template functions does not work) PR c++/9810 * call.c (build_over_call): Check access using primary template if FN is a member function template. * g++.dg/template/using8.C: New test. * g++.old-deja/g++.other/access11.C: Adjust expected error location. From-SVN: r73201 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index db68053..677deca 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2003-11-02 Kriang Lerdsuwanakij + + PR c++/9810 + * call.c (build_over_call): Check access using primary template + if FN is a member function template. + 2003-11-01 Kriang Lerdsuwanakij PR c++/12796 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e7bbd22..07622ab 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4387,7 +4387,39 @@ build_over_call (struct z_candidate *cand, int flags) joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1); if (DECL_FUNCTION_MEMBER_P (fn)) - perform_or_defer_access_check (cand->access_path, fn); + { + /* If FN is a template function, two cases must be considered. + For example: + + struct A { + protected: + template void f(); + }; + template struct B { + protected: + void g(); + }; + struct C : A, B { + using A::f; // #1 + using B::g; // #2 + }; + + In case #1 where `A::f' is a member template, DECL_ACCESS is + recorded in the primary template but not in its specialization. + We check access of FN using its primary template. + + In case #2, where `B::g' has a DECL_TEMPLATE_INFO simply + because it is a member of class template B, DECL_ACCESS is + recorded in the specialization `B::g'. We cannot use its + primary template because `B::g' and `B::g' may have + different access. */ + if (DECL_TEMPLATE_INFO (fn) + && is_member_template (DECL_TI_TEMPLATE (fn))) + perform_or_defer_access_check (cand->access_path, + DECL_TI_TEMPLATE (fn)); + else + perform_or_defer_access_check (cand->access_path, fn); + } if (args && TREE_CODE (args) != TREE_LIST) args = build_tree_list (NULL_TREE, args); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1dabd38..4c13815 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-11-02 Kriang Lerdsuwanakij + + PR c++/9810 + * g++.dg/template/using8.C: New test. + * g++.old-deja/g++.other/access11.C: Adjust expected error location. + 2003-11-02 Roger Sayle PR optimization/10817 diff --git a/gcc/testsuite/g++.dg/template/using8.C b/gcc/testsuite/g++.dg/template/using8.C new file mode 100644 index 0000000..a791587 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using8.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Sergey Shandar + +// PR c++/9810: Access checking for member function template +// appeared in using declaration. + +struct A +{ + template void F(R) {} +}; + +struct B: private A +{ + using A::F; +}; + +int main() +{ + B b; + b.F(3); +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/access11.C b/gcc/testsuite/g++.old-deja/g++.other/access11.C index 72fc333..fb97824 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/access11.C +++ b/gcc/testsuite/g++.old-deja/g++.other/access11.C @@ -5,12 +5,12 @@ class A { private: - template void g(T t) {} + template void g(T t) {} // { dg-error "" } private int i; }; template <> -void A::g(int t) { i = 1; } // { dg-error "" } private +void A::g(int t) { i = 1; } int main() {