public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Darwin] Patch c++/15428
@ 2004-05-20  1:49 Matt Austern
  2004-05-20 18:13 ` Jason Merrill
  0 siblings, 1 reply; 17+ messages in thread
From: Matt Austern @ 2004-05-20  1:49 UTC (permalink / raw)
  To: gcc-patches

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

^ permalink raw reply	[flat|nested] 17+ messages in thread
* Re: [Darwin] Patch c++/15428
@ 2004-05-25  2:40 Benjamin Kosnik
  0 siblings, 0 replies; 17+ messages in thread
From: Benjamin Kosnik @ 2004-05-25  2:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: austern, jason


../../../../fsf-mainline.expl/libstdc++-v3/src/locale-inst.cc: In instantiation of `std::__moneypunct_cache<_CharT, _Intl>& std::__moneypunct_cache<_CharT, _Intl>::operator=(conststd::__moneypunct_cache<_CharT, _Intl>&) [with _CharT = char, bool _Intl = false]':
../../../../fsf-mainline.expl/libstdc++-v3/src/locale-inst.cc:47: instantiated from here
../../../../fsf-mainline.expl/libstdc++-v3/src/locale-inst.cc:47: error: explicit instantiation of `std::__moneypunct_cache<_CharT, _Intl>& std::__moneypunct_cache<_CharT, _Intl>::operator=(conststd::__moneypunct_cache<_CharT, _Intl>&) [with _CharT = char, bool _Intl = false]' but no definition available


Matt, I too think what you are trying to do makes a great deal of sense.
It doesn't make sense to have explicit instantiations of a class when
not all of the members have been defined.

So, it's weak that libstdc++ can't deal with this, especially since I
just added these declarations to work around -Weffc++. Grrr. 

You should just add in the default definitions for these copy
constructors and assignment operators. All the locale caches will have
these.

-benjamin

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2004-06-03 22:10 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-20  1:49 [Darwin] Patch c++/15428 Matt Austern
2004-05-20 18:13 ` Jason Merrill
2004-05-20 20:28   ` Matt Austern
2004-05-20 21:02     ` Jason Merrill
2004-05-20 22:08       ` Matt Austern
2004-05-20 22:16         ` Jason Merrill
2004-05-22  8:54           ` Matt Austern
2004-05-22 12:25             ` Jason Merrill
2004-05-22 13:14               ` Matt Austern
2004-06-03 22:10             ` [Darwin] Patch c++/15428 (revised) Matt Austern
2004-06-03 22:43               ` Jason Merrill
2004-05-24 12:57           ` [Darwin] Patch c++/15428 Matt Austern
2004-05-24 21:57             ` Jason Merrill
2004-05-24 22:12               ` Matt Austern
2004-05-25  2:29                 ` Matt Austern
2004-05-25 21:43                   ` Jason Merrill
2004-05-25  2:40 Benjamin Kosnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).