aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-03-18 08:27:03 -0500
committerJason Merrill <jason@gcc.gnu.org>2002-03-18 08:27:03 -0500
commited2fa43249ffb8c69499cc8bdcadb611ccf9762a (patch)
treec8c232094f3754d4e8ba2595f50a2ca5187741d6
parentfd70bb6453ba1f09de9c507195cf2f0287b71c6e (diff)
downloadgcc-ed2fa43249ffb8c69499cc8bdcadb611ccf9762a.zip
gcc-ed2fa43249ffb8c69499cc8bdcadb611ccf9762a.tar.gz
gcc-ed2fa43249ffb8c69499cc8bdcadb611ccf9762a.tar.bz2
re PR c++/4003 (ICE on template instantiation including friendship declaration.)
PR c++/4003 * pt.c (tsubst_friend_function): Use decl_namespace_context. From-SVN: r50966
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/pt.c26
-rw-r--r--gcc/testsuite/g++.dg/template/friend.C6
3 files changed, 18 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8fc4c80..632a257 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2002-03-18 Jason Merrill <jason@redhat.com>
+ PR c++/4003 - template/friend.C
+ * pt.c (tsubst_friend_function): Use decl_namespace_context.
+
PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
* class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
type with a nontrivial destructor.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7e82b44..67da22d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4623,7 +4623,7 @@ tsubst_friend_function (decl, args)
tree template_id, arglist, fns;
tree new_args;
tree tmpl;
- tree ns = CP_DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
+ tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type));
/* Friend functions are looked up in the containing namespace scope.
We must enter that scope, to avoid finding member functions of the
@@ -6064,15 +6064,6 @@ tsubst_decl (t, args, type, complain)
SET_DECL_RTL (r, NULL_RTX);
DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
- /* For __PRETTY_FUNCTION__ we have to adjust the initializer. */
- if (DECL_PRETTY_FUNCTION_P (r))
- {
- const char *const name = (*decl_printable_name)
- (current_function_decl, 2);
- DECL_INITIAL (r) = cp_fname_init (name);
- TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
- }
-
/* Even if the original location is out of scope, the newly
substituted one is not. */
if (TREE_CODE (r) == VAR_DECL)
@@ -7353,10 +7344,6 @@ tsubst_expr (t, args, complain, in_decl)
{
init = DECL_INITIAL (decl);
decl = tsubst (decl, args, complain, in_decl);
- if (DECL_PRETTY_FUNCTION_P (decl))
- init = DECL_INITIAL (decl);
- else
- init = tsubst_expr (init, args, complain, in_decl);
if (decl != error_mark_node)
{
if (TREE_CODE (decl) != TYPE_DECL)
@@ -7372,6 +7359,17 @@ tsubst_expr (t, args, complain, in_decl)
if (TREE_CODE (decl) == VAR_DECL)
DECL_TEMPLATE_INSTANTIATED (decl) = 1;
maybe_push_decl (decl);
+ if (DECL_PRETTY_FUNCTION_P (decl))
+ {
+ /* For __PRETTY_FUNCTION__ we have to adjust the
+ initializer. */
+ const char *const name
+ = (*decl_printable_name) (current_function_decl, 2);
+ init = cp_fname_init (name);
+ TREE_TYPE (decl) = TREE_TYPE (init);
+ }
+ else
+ init = tsubst_expr (init, args, complain, in_decl);
cp_finish_decl (decl, init, NULL_TREE, 0);
}
}
diff --git a/gcc/testsuite/g++.dg/template/friend.C b/gcc/testsuite/g++.dg/template/friend.C
index 67f575e..59564ad 100644
--- a/gcc/testsuite/g++.dg/template/friend.C
+++ b/gcc/testsuite/g++.dg/template/friend.C
@@ -16,15 +16,15 @@ ostream& operator<<(ostream &o, const typename s<T>::t &x)
template <class T>
struct s {
struct t
- { // { dg-bogus "" "" { xfail *-*-* } }
+ {
friend ostream&
- operator<<<T>(ostream&, const typename s<T>::t &); // { dg-bogus "" "" { xfail *-*-* } }
+ operator<<<T>(ostream&, const typename s<T>::t &);
};
t x;
};
int main()
{
- s<int>::t y; // { dg-bogus "" "" { xfail *-*-* } }
+ s<int>::t y;
cout << y;
}