OSDN Git Service

PR c++/8511
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Nov 2002 21:57:32 +0000 (21:57 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Nov 2002 21:57:32 +0000 (21:57 +0000)
* pt.c (instantiate_decl): Handle template friends defined outside
of the class correctly.

PR c++/8511
* g++.dg/template/friend8.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59665 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend8.C [new file with mode: 0644]

index 7ff2a31..3a586ae 100644 (file)
@@ -1,3 +1,9 @@
+2002-11-30  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/8511
+       * pt.c (instantiate_decl): Handle template friends defined outside
+       of the class correctly.
+
 2002-11-29  Joe Buck <jbuck@synopsys.com>
 
        * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for
index 67252f9..99f10d5 100644 (file)
@@ -9966,7 +9966,8 @@ instantiate_decl (d, defer_ok)
      int defer_ok;
 {
   tree tmpl = DECL_TI_TEMPLATE (d);
-  tree args = DECL_TI_ARGS (d);
+  tree gen_args;
+  tree args;
   tree td;
   tree code_pattern;
   tree spec;
@@ -10000,7 +10001,8 @@ instantiate_decl (d, defer_ok)
      specializations, so we must explicitly check
      DECL_TEMPLATE_SPECIALIZATION.  */
   gen_tmpl = most_general_template (tmpl);
-  spec = retrieve_specialization (gen_tmpl, args);
+  gen_args = DECL_TI_ARGS (d);
+  spec = retrieve_specialization (gen_tmpl, gen_args);
   if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
     return spec;
 
@@ -10061,6 +10063,13 @@ instantiate_decl (d, defer_ok)
 
   code_pattern = DECL_TEMPLATE_RESULT (td);
 
+  /* In the case of a friend temlpate whose definition is provided
+     outside the class, we may have too many arguments.  Drop the ones
+     we don't need.  */
+  args = get_innermost_template_args (gen_args,
+                                     TMPL_PARMS_DEPTH 
+                                     (DECL_TEMPLATE_PARMS (td)));
+
   if (TREE_CODE (d) == FUNCTION_DECL)
     pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE);
   else
@@ -10125,8 +10134,8 @@ instantiate_decl (d, defer_ok)
 
       if (TREE_CODE (gen) == FUNCTION_DECL)
        {
-         tsubst (DECL_ARGUMENTS (gen), args, tf_error | tf_warning, d);
-         tsubst (TYPE_RAISES_EXCEPTIONS (type), args,
+         tsubst (DECL_ARGUMENTS (gen), gen_args, tf_error | tf_warning, d);
+         tsubst (TYPE_RAISES_EXCEPTIONS (type), gen_args,
                  tf_error | tf_warning, d);
          /* Don't simply tsubst the function type, as that will give
             duplicate warnings about poor parameter qualifications.
@@ -10134,7 +10143,7 @@ instantiate_decl (d, defer_ok)
             without the top level cv qualifiers.  */
          type = TREE_TYPE (type);
        }
-      tsubst (type, args, tf_error | tf_warning, d);
+      tsubst (type, gen_args, tf_error | tf_warning, d);
 
       if (DECL_CLASS_SCOPE_P (d))
        popclass ();
index ad7f449..48658bf 100644 (file)
@@ -1,3 +1,8 @@
+2002-11-30  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/8511
+       * g++.dg/template/friend8.C: New test.
+
 2002-11-29  Joe Buck <jbuck@synopsys.com>
 
        * g++.dg/lookup/anon2.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/friend8.C b/gcc/testsuite/g++.dg/template/friend8.C
new file mode 100644 (file)
index 0000000..21fd242
--- /dev/null
@@ -0,0 +1,18 @@
+template <int N> struct ivector
+{
+  template <int r, int c> friend void
+    mult_mv ();
+};
+
+template struct ivector<3>;
+
+template <int r, int c> void
+mult_mv ()
+{
+  c;
+}
+
+void get_local_point_pos ()
+{
+  mult_mv<7, 3> ();
+}