diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2004-12-15 15:21:11 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2004-12-15 15:21:11 +0000 |
commit | 6e432b319e1f52ea03345c691334c9ac80fcef85 (patch) | |
tree | fc3c8123f4c13382b40067d4d1ac457e3358cc0c | |
parent | 06d5588c56e70b6f89f3cdab25c381b237759bd7 (diff) | |
download | gcc-6e432b319e1f52ea03345c691334c9ac80fcef85.zip gcc-6e432b319e1f52ea03345c691334c9ac80fcef85.tar.gz gcc-6e432b319e1f52ea03345c691334c9ac80fcef85.tar.bz2 |
re PR c++/18825 (ICE segmentation fault in wv2)
PR c++/18825
* pt.c (instantiate_class_template): Set input_location for
friend function.
(tsubst_friend_function): Don't set input_location here.
Make sure the context is complete if necessary.
* g++.dg/template/friend32.C: New test.
From-SVN: r92200
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend32.C | 21 |
4 files changed, 72 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a879f4e..11e90b8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2004-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/18825 + * pt.c (instantiate_class_template): Set input_location for + friend function. + (tsubst_friend_function): Don't set input_location here. + Make sure the context is complete if necessary. + 2004-12-15 Nathan Sidwell <nathan@codesourcery.com> PR c++/18981 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5da2806..db9b08f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5098,9 +5098,6 @@ static tree tsubst_friend_function (tree decl, tree args) { tree new_friend; - location_t saved_loc = input_location; - - input_location = DECL_SOURCE_LOCATION (decl); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (decl) @@ -5135,8 +5132,7 @@ tsubst_friend_function (tree decl, tree args) &new_args, /*need_member_template=*/0, TREE_VEC_LENGTH (args)); - new_friend = instantiate_template (tmpl, new_args, tf_error); - goto done; + return instantiate_template (tmpl, new_args, tf_error); } new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE); @@ -5299,19 +5295,40 @@ tsubst_friend_function (tree decl, tree args) new_friend = old_decl; } } - else if (COMPLETE_TYPE_P (DECL_CONTEXT (new_friend))) + else { - /* Check to see that the declaration is really present, and, - possibly obtain an improved declaration. */ - tree fn = check_classfn (DECL_CONTEXT (new_friend), - new_friend, NULL_TREE); - - if (fn) - new_friend = fn; + tree context = DECL_CONTEXT (new_friend); + bool dependent_p; + + /* In the code + template <class T> class C { + template <class U> friend void C1<U>::f (); // case 1 + friend void C2<T>::f (); // case 2 + }; + we only need to make sure CONTEXT is a complete type for + case 2. To distinguish between the two cases, we note that + CONTEXT of case 1 remains dependent type after tsubst while + this isn't true for case 2. */ + ++processing_template_decl; + dependent_p = dependent_type_p (context); + --processing_template_decl; + + if (!dependent_p + && !complete_type_or_else (context, NULL_TREE)) + return error_mark_node; + + if (COMPLETE_TYPE_P (context)) + { + /* Check to see that the declaration is really present, and, + possibly obtain an improved declaration. */ + tree fn = check_classfn (context, + new_friend, NULL_TREE); + + if (fn) + new_friend = fn; + } } - done: - input_location = saved_loc; return new_friend; } @@ -5816,6 +5833,12 @@ instantiate_class_template (tree type) /* Build new DECL_FRIENDLIST. */ tree r; + /* The the file and line for this declaration, to + assist in error message reporting. Since we + called push_tinst_level above, we don't need to + restore these. */ + input_location = DECL_SOURCE_LOCATION (t); + if (TREE_CODE (t) == TEMPLATE_DECL) { ++processing_template_decl; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80fb3cc..1f099eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/18825 + * g++.dg/template/friend32.C: New test. + 2004-12-15 Eric Botcazou <ebotcazou@libertysurf.fr> * cpp/pragma-once-1.c: New test. diff --git a/gcc/testsuite/g++.dg/template/friend32.C b/gcc/testsuite/g++.dg/template/friend32.C new file mode 100644 index 0000000..4ce2ba3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend32.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Steven Bosscher <steven@gcc.gnu.org> +// Serge Belyshev <belyshev@lubercy.com> + +// PR c++/18825: ICE member as friend + +template<class T> class A +{ + void f (); // { dg-error "private" } +}; + +template<class T> class B +{ + friend void A<T>::f (); // { dg-error "this context" } +}; + +int f () +{ + B<int> b; // { dg-error "instantiated" } +} |