This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Darwin] Patch c++/15428
- From: Matt Austern <austern at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 May 2004 16:54:11 -0700
- Subject: [Darwin] Patch c++/15428
This patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15428 by
changing the compiler so that, on Darwin, vtables are not always
emitted as weak. This is Darwin-only because it is a violation of the
Itanium C++ ABI. It is necessary on Darwin because of a linker quirk.
(The documentation part of the patch explains the necessity.)
OK to commit to mainline?
--Matt
? gcc/.gdb_history
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.138
diff -p -r1.138 defaults.h
*** gcc/defaults.h 13 May 2004 06:39:37 -0000 1.138
--- gcc/defaults.h 19 May 2004 23:28:25 -0000
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 238,248 ****
#endif
#endif
! /* Determines whether explicit template instantiations should
! be given link-once semantics. The C++ ABI requires this
! macro to be nonzero; see the documentation. */
! #ifndef TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
! # define TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY 1
#endif
/* This determines whether or not we need linkonce unwind information
*/
--- 238,250 ----
#endif
#endif
! /* This determines whether weak symbols must be left out of a static
! archive's table of contents. Defining this macro to be nonzero has
! the consequence that certain symbols will not be made weak that
! otherwise would be. The C++ ABI requires this macro to be zero;
! see the documentation. */
! #ifndef TARGET_WEAK_NOT_IN_ARCHIVE_TOC
! #define TARGET_WEAK_NOT_IN_ARCHIVE_TOC 0
#endif
/* This determines whether or not we need linkonce unwind information
*/
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.80
diff -p -r1.80 darwin.h
*** gcc/config/darwin.h 19 May 2004 02:11:42 -0000 1.80
--- gcc/config/darwin.h 19 May 2004 23:28:25 -0000
*************** do { text_section (); \
*** 358,368 ****
#undef USE_COMMON_FOR_ONE_ONLY
#define USE_COMMON_FOR_ONE_ONLY 0
! /* The Darwin linker doesn't like explicit template instantiations to
be
! coalesced, because it doesn't want coalesced symbols to appear in
a static archive's table of contents. */
! #undef TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
! #define TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY 0
/* We make exception information linkonce. */
#undef TARGET_USES_WEAK_UNWIND_INFO
--- 358,367 ----
#undef USE_COMMON_FOR_ONE_ONLY
#define USE_COMMON_FOR_ONE_ONLY 0
! /* The Darwin linker doesn't want coalesced symbols to appear in
a static archive's table of contents. */
! #undef TARGET_WEAK_NOT_IN_ARCHIVE_TOC
! #define TARGET_WEAK_NOT_IN_ARCHIVE_TOC 1
/* We make exception information linkonce. */
#undef TARGET_USES_WEAK_UNWIND_INFO
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.708
diff -p -r1.708 decl2.c
*** gcc/cp/decl2.c 19 May 2004 01:28:56 -0000 1.708
--- gcc/cp/decl2.c 19 May 2004 23:28:25 -0000
*************** maybe_make_one_only (tree decl)
*** 1440,1446 ****
to for variables so that cp_finish_decl will update their
linkage,
because their DECL_INITIAL may not have been set properly yet.
*/
! if (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
|| (! DECL_EXPLICIT_INSTANTIATION (decl)
&& ! DECL_TEMPLATE_SPECIALIZATION (decl)))
{
--- 1440,1446 ----
to for variables so that cp_finish_decl will update their
linkage,
because their DECL_INITIAL may not have been set properly yet.
*/
! if (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC
|| (! DECL_EXPLICIT_INSTANTIATION (decl)
&& ! DECL_TEMPLATE_SPECIALIZATION (decl)))
{
*************** maybe_emit_vtables (tree ctype)
*** 1581,1586 ****
--- 1581,1587 ----
tree vtbl;
tree primary_vtbl;
bool needed = false;
+ bool weaken_vtables;
/* If the vtables for this class have already been emitted there is
nothing more to do. */
*************** maybe_emit_vtables (tree ctype)
*** 1611,1616 ****
--- 1612,1640 ----
else if (TREE_PUBLIC (vtbl) && !DECL_COMDAT (vtbl))
needed = true;
+ /* Determine whether to make vtables weak. The ABI requires that we
+ do so. There are two cases in which we have to violate the ABI
+ specification: targets where we don't have weak symbols
+ (obviously), and targets where weak symbols don't appear in
+ static archives' tables of contents. On such targets, avoiding
+ undefined symbol link errors requires that we only make a symbol
+ weak if we know that it will be emitted everywhere it's needed.
+ So on such targets we don't make vtables weak in the common case
+ where we're emitting a vtable of a nontemplate class in the
+ translation unit containing the definition of a noninline key
+ method. */
+ if (flag_weak && !TARGET_WEAK_NOT_IN_ARCHIVE_TOC)
+ weaken_vtables = true;
+ else if (flag_weak)
+ {
+ if (CLASSTYPE_USE_TEMPLATE (ctype))
+ weaken_vtables = CLASSTYPE_IMPLICIT_INSTANTIATION (ctype);
+ else
+ weaken_vtables = !CLASSTYPE_KEY_METHOD (ctype)
+ || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (ctype));
+ }
+ else
+ weaken_vtables = false;
/* The ABI requires that we emit all of the vtables if we emit any
of them. */
*************** maybe_emit_vtables (tree ctype)
*** 1657,1664 ****
DECL_IGNORED_P (vtbl) = 1;
}
! /* Always make vtables weak. */
! if (flag_weak)
comdat_linkage (vtbl);
rest_of_decl_compilation (vtbl, NULL, 1, 1);
--- 1681,1688 ----
DECL_IGNORED_P (vtbl) = 1;
}
! /* Always make vtables weak. Or at least almost always; see
above. */
! if (weaken_vtables)
comdat_linkage (vtbl);
rest_of_decl_compilation (vtbl, NULL, 1, 1);
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.851
diff -p -r1.851 pt.c
*** gcc/cp/pt.c 13 May 2004 06:40:21 -0000 1.851
--- gcc/cp/pt.c 19 May 2004 23:28:25 -0000
*************** do_type_instantiation (tree t, tree stor
*** 10789,10795 ****
get unresolved symbols at link time. */
explicitly_instantiate_members =
! TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
&& previous_instantiation_extern_p && ! extern_p
&& ! TYPE_FOR_JAVA (t);
--- 10789,10795 ----
get unresolved symbols at link time. */
explicitly_instantiate_members =
! !TARGET_WEAK_NOT_IN_ARCHIVE_TOC
&& previous_instantiation_extern_p && ! extern_p
&& ! TYPE_FOR_JAVA (t);
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.325
diff -p -r1.325 tm.texi
*** gcc/doc/tm.texi 19 May 2004 13:54:15 -0000 1.325
--- gcc/doc/tm.texi 19 May 2004 23:28:28 -0000
*************** commands that will make the symbol(s) as
*** 6759,6771 ****
hidden, protected or internal visibility as specified by
@var{visibility}.
@end deftypefn
! @defmac TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
A C expression that evaluates to true if the target's linker expects
! explicit template specializations, as well as implicit, to be given
! linkonce semantics. The default is @code{1}. The C++ ABI requires
! this macro to be nonzero. Define this macro for targets where full
! C++ ABI compliance is impossible and where explicit and implicit
! template specialization must be treated differently.
@end defmac
@defmac TARGET_SUPPORTS_HIDDEN
--- 6759,6781 ----
hidden, protected or internal visibility as specified by
@var{visibility}.
@end deftypefn
! @defmac TARGET_WEAK_NOT_IN_ARCHIVE_TOC
A C expression that evaluates to true if the target's linker expects
! that weak symbols do not appear in a static archive's table of
contents.
! The default is @code{0}.
!
! Leaving weak symbols out of an archive's table of contents means that,
! if a symbol will only have a definition in one translation unit and
! will have undefined references from other translation units, that
! symbol should not be weak. Defining this macro to be nonzero will
! thus have the effect that certain symbols that would normally be weak
! (explicit template instantiations, and vtables for polymorphic classes
! with noninline key methods) will instead be nonweak.
!
! The C++ ABI requires this macro to be zero. Define this macro for
! targets where full C++ ABI compliance is impossible and where linker
! restrictions require weak symbols to be left out of a static archive's
! table of contents.
@end defmac
@defmac TARGET_SUPPORTS_HIDDEN