aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-11-30 21:57:32 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-11-30 21:57:32 +0000
commit65f8b0fbafee3584579c96a9a0efc27ff6ea4519 (patch)
tree97af7edbd722cf6428fce54bed621cb699c06275 /gcc/cp
parentacb45e09fe1fb5189fa0f24235ee98fe3626b821 (diff)
downloadgcc-65f8b0fbafee3584579c96a9a0efc27ff6ea4519.zip
gcc-65f8b0fbafee3584579c96a9a0efc27ff6ea4519.tar.gz
gcc-65f8b0fbafee3584579c96a9a0efc27ff6ea4519.tar.bz2
re PR c++/8511 ((hopefully) reproducible cc1plus SIGSEGV.)
PR c++/8511 * pt.c (instantiate_decl): Handle template friends defined outside of the class correctly. PR c++/8511 * g++.dg/template/friend8.C: New test. From-SVN: r59665
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c19
2 files changed, 20 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7ff2a31..3a586ae 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 67252f9..99f10d5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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 ();