This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 8511
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: zack at codesourcery dot com
- Date: Sat, 30 Nov 2002 14:02:37 -0800
- Subject: C++ PATCH: PR 8511
- Reply-to: mark at codesourcery dot com
Zack was kind enough to cut this template instantiation problem down
to a small test case. This patch fixes the problem.
Tested on i686-pc-linux-gnu, applied on the mainline.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
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-30 Mark Mitchell <mark@codesourcery.com>
PR c++/8511
* g++.dg/template/friend8.C: New test.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.631
diff -c -5 -p -r1.631 pt.c
*** cp/pt.c 20 Nov 2002 05:17:01 -0000 1.631
--- cp/pt.c 30 Nov 2002 21:55:01 -0000
*************** tree
*** 9964,9974 ****
instantiate_decl (d, defer_ok)
tree d;
int defer_ok;
{
tree tmpl = DECL_TI_TEMPLATE (d);
! tree args = DECL_TI_ARGS (d);
tree td;
tree code_pattern;
tree spec;
tree gen_tmpl;
int pattern_defined;
--- 9964,9975 ----
instantiate_decl (d, defer_ok)
tree d;
int defer_ok;
{
tree tmpl = DECL_TI_TEMPLATE (d);
! tree gen_args;
! tree args;
tree td;
tree code_pattern;
tree spec;
tree gen_tmpl;
int pattern_defined;
*************** instantiate_decl (d, defer_ok)
*** 9998,10008 ****
there's no reason to instantiate it. Note that
retrieve_specialization gives us both instantiations and
specializations, so we must explicitly check
DECL_TEMPLATE_SPECIALIZATION. */
gen_tmpl = most_general_template (tmpl);
! spec = retrieve_specialization (gen_tmpl, args);
if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
return spec;
/* This needs to happen before any tsubsting. */
if (! push_tinst_level (d))
--- 9999,10010 ----
there's no reason to instantiate it. Note that
retrieve_specialization gives us both instantiations and
specializations, so we must explicitly check
DECL_TEMPLATE_SPECIALIZATION. */
gen_tmpl = most_general_template (tmpl);
! gen_args = DECL_TI_ARGS (d);
! spec = retrieve_specialization (gen_tmpl, gen_args);
if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
return spec;
/* This needs to happen before any tsubsting. */
if (! push_tinst_level (d))
*************** instantiate_decl (d, defer_ok)
*** 10059,10068 ****
--- 10061,10077 ----
td = DECL_TI_TEMPLATE (td);
}
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
pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
*************** instantiate_decl (d, defer_ok)
*** 10123,10142 ****
if (DECL_CLASS_SCOPE_P (d))
pushclass (DECL_CONTEXT (d), 1);
if (TREE_CODE (gen) == FUNCTION_DECL)
{
! tsubst (DECL_ARGUMENTS (gen), args, tf_error | tf_warning, d);
! tsubst (TYPE_RAISES_EXCEPTIONS (type), args,
tf_error | tf_warning, d);
/* Don't simply tsubst the function type, as that will give
duplicate warnings about poor parameter qualifications.
The function arguments are the same as the decl_arguments
without the top level cv qualifiers. */
type = TREE_TYPE (type);
}
! tsubst (type, args, tf_error | tf_warning, d);
if (DECL_CLASS_SCOPE_P (d))
popclass ();
}
--- 10132,10151 ----
if (DECL_CLASS_SCOPE_P (d))
pushclass (DECL_CONTEXT (d), 1);
if (TREE_CODE (gen) == FUNCTION_DECL)
{
! 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.
The function arguments are the same as the decl_arguments
without the top level cv qualifiers. */
type = TREE_TYPE (type);
}
! tsubst (type, gen_args, tf_error | tf_warning, d);
if (DECL_CLASS_SCOPE_P (d))
popclass ();
}
Index: testsuite/g++.dg/template/friend8.C
===================================================================
RCS file: testsuite/g++.dg/template/friend8.C
diff -N testsuite/g++.dg/template/friend8.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/friend8.C 30 Nov 2002 21:55:04 -0000
***************
*** 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> ();
+ }