This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Darwin] Patch c++/15428 (revised)


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.)

What has changed since the previous version of this patch: this version is slightly simpler. The earlier version touched the logic that determined whether members of an explicitly instantiated class template should be instantiated implicitly or explicitly. That's now unnecessary, because that logic no longer exists.

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.139 diff -p -r1.139 defaults.h *** gcc/defaults.h 30 May 2004 18:32:24 -0000 1.139 --- gcc/defaults.h 3 Jun 2004 21:40:58 -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 3 Jun 2004 21:40:58 -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.712
diff -p -r1.712 decl2.c
*** gcc/cp/decl2.c 2 Jun 2004 21:12:52 -0000 1.712
--- gcc/cp/decl2.c 3 Jun 2004 21:40:59 -0000
*************** maybe_make_one_only (tree decl)
*** 1441,1447 ****
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)))
{
--- 1441,1447 ----
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)
*** 1582,1587 ****
--- 1582,1588 ----
    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)
*** 1612,1617 ****
--- 1613,1641 ----
    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)
*** 1658,1665 ****
  	  DECL_IGNORED_P (vtbl) = 1;
  	}

!       /* Always make vtables weak.  */
!       if (flag_weak)
  	comdat_linkage (vtbl);

        rest_of_decl_compilation (vtbl, NULL, 1, 1);
--- 1682,1689 ----
  	  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/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.326
diff -p -r1.326 tm.texi
*** gcc/doc/tm.texi 21 May 2004 01:03:20 -0000 1.326
--- gcc/doc/tm.texi 3 Jun 2004 21:41:03 -0000
*************** commands that will make the symbol(s) as
*** 6753,6765 ****
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
--- 6753,6775 ----
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]