re PR c++/9810 (Using-declaration for template functions does not work)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Sun, 2 Nov 2003 14:17:39 +0000 (14:17 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Sun, 2 Nov 2003 14:17:39 +0000 (14:17 +0000)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/using8.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/access11.C

index db68053..677deca 100644 (file)
@@ -1,3 +1,9 @@
+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-01  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/12796
index e7bbd22..07622ab 100644 (file)
@@ -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 <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);
index 1dabd38..4c13815 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2003-11-02  Roger Sayle  <roger@eyesopen.com>
 
        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 (file)
index 0000000..a791587
--- /dev/null
@@ -0,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);
+}
index 72fc333..fb97824 100644 (file)
@@ -5,12 +5,12 @@
 class A
 {
 private:
-  template <class T> void g(T t)  {}
+  template <class T> void g(T t)  {} // { dg-error "" } private
   int i;
 };
 
 template <>
-void A::g<int>(int t) { i = 1; } // { dg-error "" } private
+void A::g<int>(int t) { i = 1; }
 
 int main()
 {