aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-04-07 11:54:42 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-04-07 11:54:42 -0400
commitfeb3b88ad7ea6de3d0f63b41226f0b90c36a0c07 (patch)
treecff0e08f71b364fc0ce4649355d0bef0429f0ea4
parent7dcfe861f19429326f0b82c4fdccd7d7088ae68b (diff)
downloadgcc-feb3b88ad7ea6de3d0f63b41226f0b90c36a0c07.zip
gcc-feb3b88ad7ea6de3d0f63b41226f0b90c36a0c07.tar.gz
gcc-feb3b88ad7ea6de3d0f63b41226f0b90c36a0c07.tar.bz2
re PR c++/38392 (Template friend function injection)
PR c++/38392 * pt.c (tsubst_friend_function): Instatiate a friend that has already been used. From-SVN: r158073
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/friend51.C17
4 files changed, 36 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d3b0788..6e048ca 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2010-04-07 Jason Merrill <jason@redhat.com>
+ PR c++/38392
+ * pt.c (tsubst_friend_function): Instatiate a friend that has already
+ been used.
+
* pt.c (print_template_statistics): New.
* cp-tree.h: Declare it.
* tree.c (cxx_print_statistics): Call it.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d1c33d6..1c0e13e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7330,11 +7330,18 @@ tsubst_friend_function (tree decl, tree args)
DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
if (TREE_CODE (old_decl) != TEMPLATE_DECL)
- /* We should have called reregister_specialization in
- duplicate_decls. */
- gcc_assert (retrieve_specialization (new_template,
- new_args, 0)
- == old_decl);
+ {
+ /* We should have called reregister_specialization in
+ duplicate_decls. */
+ gcc_assert (retrieve_specialization (new_template,
+ new_args, 0)
+ == old_decl);
+
+ /* Instantiate it if the global has already been used. */
+ if (DECL_ODR_USED (old_decl))
+ instantiate_decl (old_decl, /*defer_ok=*/true,
+ /*expl_inst_class_mem_p=*/false);
+ }
else
{
tree t;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3138c8a..3df0787 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2010-04-07 Jason Merrill <jason@redhat.com>
+ PR c++/38392
+ * g++.dg/template/friend51.C: New test.
+
PR c++/41970
* g++.old-deja/g++.other/linkage1.C: Adjust.
diff --git a/gcc/testsuite/g++.dg/template/friend51.C b/gcc/testsuite/g++.dg/template/friend51.C
new file mode 100644
index 0000000..d2d1ad7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend51.C
@@ -0,0 +1,17 @@
+// PR c++/38392
+// { dg-do link }
+
+void Function();
+
+int main()
+{
+ Function();
+}
+
+template <typename T>
+struct Test
+{
+ friend void Function() { }
+};
+
+template class Test<int>;