This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR c++/10551
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Apr 2003 15:17:42 -0700
- Subject: C++ PATCH: PR c++/10551
- Reply-to: mark at codesourcery dot com
This patch fixes a regression introduced by what has now turned into a
complete reorganization of the linkage-computation code in the C++
front end. This is one of those things where you pull on one string,
and the whole thing unravels -- but at least now there is a coherent
picture of how it ought to work, so it's more obvious what's a bug and
what's not...
Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-04-29 Mark Mitchell <mark@codesourcery.com>
PR c++/10551
* pt.c (mark_decl_instantiated): Defer all explicit instantiations
that have not yet been written out.
2003-04-29 Mark Mitchell <mark@codesourcery.com>
PR c++/10551
* g++.dg/template/explicit1.C: New test.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.635.2.21
diff -c -5 -p -r1.635.2.21 pt.c
*** cp/pt.c 27 Apr 2003 19:29:25 -0000 1.635.2.21
--- cp/pt.c 29 Apr 2003 22:11:10 -0000
*************** unify (tparms, targs, parm, arg, strict)
*** 9359,9381 ****
void
mark_decl_instantiated (result, extern_p)
tree result;
int extern_p;
{
- if (TREE_CODE (result) != FUNCTION_DECL)
- /* The TREE_PUBLIC flag for function declarations will have been
- set correctly by tsubst. */
- TREE_PUBLIC (result) = 1;
-
/* We used to set this unconditionally; we moved that to
do_decl_instantiation so it wouldn't get set on members of
explicit class template instantiations. But we still need to set
it here for the 'extern template' case in order to suppress
implicit instantiations. */
if (extern_p)
SET_DECL_EXPLICIT_INSTANTIATION (result);
if (! extern_p)
{
DECL_INTERFACE_KNOWN (result) = 1;
DECL_NOT_REALLY_EXTERN (result) = 1;
--- 9359,9386 ----
void
mark_decl_instantiated (result, extern_p)
tree result;
int extern_p;
{
/* We used to set this unconditionally; we moved that to
do_decl_instantiation so it wouldn't get set on members of
explicit class template instantiations. But we still need to set
it here for the 'extern template' case in order to suppress
implicit instantiations. */
if (extern_p)
SET_DECL_EXPLICIT_INSTANTIATION (result);
+ /* If this entity has already been written out, it's too late to
+ make any modifications. */
+ if (TREE_ASM_WRITTEN (result))
+ return;
+
+ if (TREE_CODE (result) != FUNCTION_DECL)
+ /* The TREE_PUBLIC flag for function declarations will have been
+ set correctly by tsubst. */
+ TREE_PUBLIC (result) = 1;
+
if (! extern_p)
{
DECL_INTERFACE_KNOWN (result) = 1;
DECL_NOT_REALLY_EXTERN (result) = 1;
*************** mark_decl_instantiated (result, extern_p
*** 9385,9395 ****
/* For WIN32 we also want to put explicit instantiations in
linkonce sections. */
else if (TREE_PUBLIC (result))
maybe_make_one_only (result);
}
! else if (TREE_CODE (result) == FUNCTION_DECL)
defer_fn (result);
}
/* Given two function templates PAT1 and PAT2, return:
--- 9390,9401 ----
/* For WIN32 we also want to put explicit instantiations in
linkonce sections. */
else if (TREE_PUBLIC (result))
maybe_make_one_only (result);
}
!
! if (TREE_CODE (result) == FUNCTION_DECL)
defer_fn (result);
}
/* Given two function templates PAT1 and PAT2, return:
Index: testsuite/g++.dg/template/explicit1.C
===================================================================
RCS file: testsuite/g++.dg/template/explicit1.C
diff -N testsuite/g++.dg/template/explicit1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/explicit1.C 29 Apr 2003 22:11:11 -0000
***************
*** 0 ****
--- 1,17 ----
+ // { dg-do link }
+ // { dg-options "-fno-implicit-templates" }
+
+ template <class T> struct C {
+ ~C();
+ };
+ template <class T> C<T>::~C() {}
+
+ struct X {
+ C<X> *p;
+ ~X() { delete p; }
+ };
+
+ template class C<X>;
+ C<X> x;
+
+ int main () {}