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


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


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