This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH,committed] Fix PR9810 (Access-declaration handling formember function template)


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()
  {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]