This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH,committed] Fix PR9810 (Access-declaration handling formember function template)
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 2 Nov 2003 21:27:19 +0700 (ICT)
- Subject: [C++ PATCH,committed] Fix PR9810 (Access-declaration handling formember function template)
- Reply-to: <lerdsuwa at users dot sourceforge dot net>
Hi
This patch corrects access declaration handling when the access of
member template function is modified. DECL_ACCESS is recorded in
its primary template, not in instantiations or specializations.
This is explained in detail in the comment in the patch.
Alternative solution, making DECL_ACCESS correct for instantiations
etc. is not attractive since instantiation and access declaration
can appear in any order. This requires tsubst'ing DECL_ACCESS during
instantiation, and updating DECL_ACCESS already instantiated
templates when parsing access declaration.
Tested on i686-pc-linux-gnu. Committed to trunk as obvious.
--Kriang
2003-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/9810
* call.c (build_over_call): Check access using primary template
if FN is a member function template.
2003-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/9810
* g++.dg/template/using8.C: New test.
* g++.old-deja/g++.other/access11.C: Adjust expected error location.
diff -cprN gcc-main-save/gcc/cp/call.c gcc-main-new/gcc/cp/call.c
*** gcc-main-save/gcc/cp/call.c Fri Oct 24 21:39:22 2003
--- gcc-main-new/gcc/cp/call.c Sat Nov 1 22:23:19 2003
*************** build_over_call (struct z_candidate *can
*** 4387,4393 ****
joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
if (DECL_FUNCTION_MEMBER_P (fn))
! perform_or_defer_access_check (cand->access_path, fn);
if (args && TREE_CODE (args) != TREE_LIST)
args = build_tree_list (NULL_TREE, args);
--- 4387,4425 ----
joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
if (DECL_FUNCTION_MEMBER_P (fn))
! {
! /* If FN is a template function, two cases must be considered.
! For example:
!
! struct A {
! protected:
! template <class T> void f();
! };
! template <class T> struct B {
! protected:
! void g();
! };
! struct C : A, B<int> {
! using A::f; // #1
! using B<int>::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<int>::g' has a DECL_TEMPLATE_INFO simply
! because it is a member of class template B, DECL_ACCESS is
! recorded in the specialization `B<int>::g'. We cannot use its
! primary template because `B<T>::g' and `B<int>::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 -cprN gcc-main-save/gcc/testsuite/g++.dg/template/using8.C gcc-main-new/gcc/testsuite/g++.dg/template/using8.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/using8.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/using8.C Sun Oct 26 21:36:57 2003
***************
*** 0 ****
--- 1,22 ----
+ // { dg-do compile }
+
+ // Origin: Sergey Shandar <comer@pisem.net>
+
+ // PR c++/9810: Access checking for member function template
+ // appeared in using declaration.
+
+ struct A
+ {
+ template<class R> void F(R) {}
+ };
+
+ struct B: private A
+ {
+ using A::F;
+ };
+
+ int main()
+ {
+ B b;
+ b.F(3);
+ }
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.other/access11.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.other/access11.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.other/access11.C Thu May 1 18:35:13 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.other/access11.C Sat Nov 1 22:55:19 2003
***************
*** 5,16 ****
class A
{
private:
! template <class T> void g(T t) {}
int i;
};
template <>
! void A::g<int>(int t) { i = 1; } // { dg-error "" } private
int main()
{
--- 5,16 ----
class A
{
private:
! template <class T> void g(T t) {} // { dg-error "" } private
int i;
};
template <>
! void A::g<int>(int t) { i = 1; }
int main()
{