aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c19
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/friend8.C18
4 files changed, 43 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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ad7f449..48658bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..21fd242
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend8.C
@@ -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> ();
+}