public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [Darwin] Patch: enable linkonce support for Darwin
@ 2004-01-29 17:42 Matt Austern
  2004-01-30 16:53 ` [Darwin] Patch, take 2: " Matt Austern
  0 siblings, 1 reply; 17+ messages in thread
From: Matt Austern @ 2004-01-29 17:42 UTC (permalink / raw)
  To: gcc, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 7366 bytes --]

This patch enables linkonce support, a.k.a. vague linkage, a.k.a 
comdat, for Darwin.  It fixes a bunch of test case failures from g++.dg 
and g++.old-deja.  (init/init-ref4.C, parse/attr-ctor1.C, 
parse/constant4.C, template/non-dependent2.C, 
template/non-dependent3.C, g++.other/comdat3.C, g++.other/mangle3.C, 
g++.pt/static3.C, g++.pt/static6.C) It also fixes 
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11026, which is a P2 bug.

Testing: bootstrapped (C, C++, Java) on OS X 10.3, no regressions in 
the C, C++, or libstdc++ testsuites.


OK, this is a large and invasive patch (but with one important feature: 
I claim it is obvious that this patch will not change the behavior of 
the compiler on any platform other than Darwin).  So I should walk 
people through some of the high points.  Most of the patch is pretty 
clear if you think about it in terms of Darwin linker features.

Vague linkage on Darwin uses a feature called coalescing, which is sort 
of like ELF weak symbols and sort of like GNU linkonce sections except 
that it's not all that much like either of them.  A coalesced symbol 
must be marked with the .weak_definition directive and must also appear 
in a section that is marked with the "coalesced" flag.  These aren't 
like GNU linkonce sections because we have many symbols per coalesced 
section, not one section per symbol.  All coalesced function 
definitions, for example, go in __TEXT,__textcoal_nt.  References to 
coalesced symbols must be indirect, even if the compiler thinks it sees 
a definition of a coalesced symbol in the same translation unit as the 
use.  Coalescing is only for defined symbols, and only applies to 
symbols with global or private extern scope.

The Darwin linker doesn't have a notion of subsections, so coalescing 
simply works at the level of things between one nonlocal symbol (a 
nonlocal symbol starts with something other than "L") and the next.  A 
coalesced section must begin with a nonlocal symbol.

Exceptions are an annoying problem.  Here's the problem scenerio: 
suppose an FDE in a .o refers to local symbols in a coalesced function 
from that same .o, and now suppose that particular copy of the 
coalesced function gets discarded by the linker.  In that case, the 
dangling reference will cause the Darwin linker to die horribly.  The 
solution we came up with, which Apple has been using in our locally 
modified compiler for two years, is to coalesce FDEs too.  We give 
every FDE its own symbol (the name we choose is <foo>.eh, where <foo> 
is the assembler name of the function the FDE corresponds to), so that 
the FDEs too are coalesced.  We make sure that a function and its FDE 
always have the same scope and visibility; the idea is that if the 
linker discards a coalesced function, it will also discard the 
corresponding coalesced FDE.  There's one little subtlety involving 
implicit instantiations that have FDEs and explicit instantiations that 
don't, and we solve that by sometimes generating dummy FDE labels.   
This is admittedly a crude scheme; you can think of it as "poor man's 
group COMDAT".  It's probably the best we can do given the Darwin 
linker, though, and Apple has shown that it can actually work.

To support all this exception machinery I put in a link from 
dw_fde_struct back to the associated decl (we'll need that for other 
targets, anyway, when and if we move to ELF group COMDAT), and I 
introduced a new target macro, ASM_OUTPUT_UNWIND_LABEL, to give FDEs 
their labels.  Everywhere but Darwin, that macro does nothing.

Two minor quirks of the Darwin linker that we have to accommodate.

First quirk: coalesced symbols can't be put in a static archive's table 
of contents.  If the linker sees a static archive with duplicate TOC 
entries, it will give an unfriendly warning and then behave 
unpredictably.  That's why (as you'll see if you look in the darwin.c 
section of my patch) the __TEXT,__textcoal_nt section is given the 
"no_toc" flag.  OK, what's the consequence of this?  Since you'll never 
find a coalesced symbol from the TOC, you have to make sure a symbol 
will only be marked as coalesced if it's something that can be 
regenerated in every translation unit where it's needed.  There's 
exactly one obscure corner case where it matters: explicit 
instantiation of a class template that's marked as "extern".  The 
question is whether explicit instantiation of a class template triggers 
explicit or implicit instantiation of its member functions.  As it 
stands, the compiler does an implicit instantiation (with a note in the 
comments saying that the standard doesn't say which one it should do).  
My patch keeps that behavior in general, but makes it an explicit 
instantiation, thus something that will appear in the TOC, for Darwin 
in the special case where we're explicitly instantiating a previously 
extern template.  I introduced a new target macro,  TARGET_WEAK_NO_TOC, 
to control this behavior.

Second quirk: Common is bad news.  Common symbols in Darwin can't have 
hidden visibility and can't be exported from dylibs.   The second is 
deliberate and the first is a bug, but both of them are things we have 
to deal with.  So we really just shouldn't ever use common to implement 
vague linkage, we should always use coalescing instead.  I introduced 
another target macro, USE_COMMON_FOR_ONE_ONLY, so we can tell the 
compiler about targets where common is a poor choice for representing 
vague linkage.  (Again: this is not the same thing as -fno-common.  
Common is fine in its place, just not for vague linkage.)

Finally, one new user-visible feature: -fhidden-weak.  This flag makes 
the compiler automatically give hidden visibility to symbols that have 
vague linkage.  This feature has proved useful in Apple compilers, 
because sometimes exporting coalesced symbols from dylibs interacts 
poorly with some of our more complicated linker features.  I also have 
the sense from C++ standardization committee discussions that, if the 
committee ever standardizes dynamic libraries, something like this is 
the direction things are likely to go.  I haven't made -fhidden-weak 
the default on any platform, not even Darwin, but I've left in the 
machinery so it can be made the default.   Two more target macros 
associated with this: TARGET_SUPPORTS_HIDDEN (no, HAVE_GAS_HIDDEN 
doesn't cover this; see the comments, and see also the place in the 
configure script where HAVE_GAS_HIDDEN is set) and  
DEFAULT_USE_HIDDEN_WEAK.

Potentially questionable decisions.  First, I'm keying this off 
DECL_ONE_ONLY, not DECL_WEAK.  I don't have strong feelings about this, 
but I think it's a slightly better choice.  DECL_WEAK has just a little 
too much baggage associated with it, and there are too many places in 
the back end that think that DECL_WEAK means all of the things that 
weak symbols mean on ELF.  Second, I've introduced target macros and 
not target hooks.  Again I don't have a strong preference, but (this is 
subjective) in my opinion target macros were more consistent with 
existing style.  The sorts of things I'm doing here seemed more like 
the things people are currently doing with target macros than like the 
things people are currently doing with hooks.

Whew!  I hope I've answered most of the major questions here.  Now the 
patch.

OK to commit to mainline?

				--Matt



[-- Attachment #2: weak-darwin.txt --]
[-- Type: text/plain, Size: 45440 bytes --]

Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.2552
diff -p -r2.2552 ChangeLog
*** gcc/ChangeLog	29 Jan 2004 15:59:09 -0000	2.2552
--- gcc/ChangeLog	29 Jan 2004 16:00:16 -0000
***************
*** 1,3 ****
--- 1,61 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 
+ 	* c-opts.c (c_common_handle_option): Add -fhidden-weak option.
+ 	* c.opt: Ditto.
+ 	* flags.h (flag_hidden_weak): flag corresponding to -fhidden-weak.
+ 	* toplev.c (flag_hidden_weak): Ditto.
+ 	* default.h (ASM_OUTPUT_UNWIND_LABEL): New target macro.
+ 	(TARGET_WEAK_NO_TOC): New target macro.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): New target macro.
+ 	(TARGET_SUPPORTS_HIDDEN): New target macro.
+ 	(DEFAULT_USE_HIDDEN_WEAK): New target macro.
+ 	(USE_COMMON_FOR_ONE_ONLY): New target macro.
+ 	* dwarf2out.c (struct dw_fde_struct): Add field for function decl
+ 	that corresponds to this FDE.
+ 	(FRAME_BEGIN_LABEL): Allow target to override default label.
+ 	(output_call_frame_info): If FDEs are linknonce, then use extra
+ 	indirection for FDE encoding, output a label for each FDE, and 
+ 	output an empty label for each function without an FDE.
+ 	(dwarf2out_begin_prologue): Set up decl field when creating an FDE.
+ 	* varasm.c (globalize_decl): Call ASM_MAKE_LABEL_LINKONCE for
+ 	decls with DECL_ONE_ONLY set, if that macro is defined.
+ 	(make_decl_one_only): On systems where USE_COMMON_FOR_ONE_ONLY is
+ 	false, don't use DECL_COMMON, instead use DECL_ONE_ONLY.
+ 	* config/darwin-protos.h (darwin_unique_section): Declare.
+ 	(darwin_asm_named_section): Ditto.
+ 	(darwin_section_type_flags): Ditto.
+ 	(darwin_non_lazy_pcrel): Ditto.
+ 	(darwin_output_unwind_label): Ditto.
+ 	(darwin_make_decl_one_only): Ditto.
+ 	* config/darwin.c (machopic_finish): Get rid of tweak that
+ 	eliminate stubs for symbols that are defined.
+ 	(darwin_encode_section_info): Don't treat weak functiosn as defined.
+ 	(darwin_make_decl_one_only): Define.
+ 	(darwin_asm_named_section): Ditto.
+ 	(darwin_section_type_flags): Ditto.
+ 	(darwin_unique_section): Ditto.
+ 	(darwin_output_unwind_label): Ditto.
+ 	(darwin_non_lazy_pcrel): Ditto.
+ 	(darwin_asm_output_dwarf_delta): Difference between two labels is
+ 	local only if both labels are local.
+ 	* config/darwin.h (MAKE_DECL_ONE_ONLY): Define.
+ 	(ASM_MAKE_LABEL_LINKONCE): Ditto.
+ 	(TARGET_SUPPORTS_HIDDEN): Ditto.
+ 	(DEFAULT_USE_HIDDEN_WEAK): Ditto.
+ 	(USE_COMMON_FOR_ONE_ONLY): Ditto.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): Ditto.
+ 	(FRAME_BEGIN_LABEL): Ditto.
+ 	(ASM_OUTPUT_UNWIND_LABEL): Ditto.
+ 	(ASM_DECLARE_OBJECT_NAME): Make references to weak symbols indirect.
+ 	(ASM_DECLARE_FUNCTION_NAME): Ditto.
+ 	(darwin_eh_frame_section): Give __eh_frame section the coalesced flag.
+ 	(TARGET_ASM_UNIQUE_SECTION): Define.
+ 	(EH_FRAME_SECTION_NAME): Define.
+ 	(EH_FRAME_SECTION_ATTR): Ditto.
+ 	(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Ditto.
+ 	(TARGET_ASM_NAMED_SECTION): Ditto.
+ 	(TARGET_SECTION_TYPE_FLAGS): Ditto.
+ 	
  2004-01-29  Kazu Hirata  <kazu@cs.umass.edu>
  
  	* config/frv/frv.c: Don't mention deprecated macros in
Index: gcc/c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.98
diff -p -r1.98 c-opts.c
*** gcc/c-opts.c	21 Jan 2004 20:39:51 -0000	1.98
--- gcc/c-opts.c	29 Jan 2004 16:00:17 -0000
*************** c_common_handle_option (size_t scode, co
*** 916,921 ****
--- 916,932 ----
        flag_weak = value;
        break;
  
+     case OPT_fhidden_weak:
+       flag_hidden_weak = value;
+ #if !TARGET_SUPPORTS_HIDDEN
+       if (value)
+ 	{
+ 	  warning ("-fhidden-weak not supported for this target, ignored");
+ 	  flag_hidden_weak = 0;
+ 	}
+ #endif
+       break;
+ 
      case OPT_fzero_link:
        flag_zero_link = value;
        break;
Index: gcc/c.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c.opt,v
retrieving revision 1.17
diff -p -r1.17 c.opt
*** gcc/c.opt	25 Sep 2003 01:25:50 -0000	1.17
--- gcc/c.opt	29 Jan 2004 16:00:17 -0000
*************** fweak
*** 666,671 ****
--- 666,675 ----
  C++ ObjC++
  Emit common-like symbols as weak symbols
  
+ fhidden-weak
+ C++ ObjC++
+ Give weak symbols hidden visibility on targets that support it
+ 
  fwide-exec-charset=
  C ObjC C++ ObjC++ Joined RejectNegative
  -fwide-exec-charset=<cset>	Convert all wide strings and character constants to character set <cset>
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.126
diff -p -r1.126 defaults.h
*** gcc/defaults.h	21 Jan 2004 20:39:53 -0000	1.126
--- gcc/defaults.h	29 Jan 2004 16:00:18 -0000
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 219,224 ****
--- 219,232 ----
  #endif
  #endif
  
+ /* How to emit a nonlocal label for FDEs.  Default is to do nothing,
+    because most targets don't need such labels. The meaning of the 
+    first two parameters is obvious.  The third is a boolean: true if
+    this is a placeholder label for an omitted FDE. */
+ #ifndef ASM_OUTPUT_UNWIND_LABEL
+ #define ASM_OUTPUT_UNWIND_LABEL(FILE, DECL, EMPTY) do { } while(0)
+ #endif
+ 
  /* This determines whether or not we support weak symbols.  */
  #ifndef SUPPORTS_WEAK
  #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 237,242 ****
--- 245,262 ----
  #endif
  #endif
  
+ /* Determines whether symbols with link-once semantics should be given
+    special treatments so that they don't get put in the table of
+    contents of a static archive. */
+ #ifndef TARGET_WEAK_NO_TOC
+ # define TARGET_WEAK_NO_TOC 0
+ #endif
+ 
+ /* This determines whether or not we need linkonce unwind information */
+ #ifndef TARGET_USES_WEAK_UNWIND_INFO
+ #define TARGET_USES_WEAK_UNWIND_INFO 0
+ #endif
+ 
  /* By default, there is no prefix on user-defined symbols.  */
  #ifndef USER_LABEL_PREFIX
  #define USER_LABEL_PREFIX ""
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 257,262 ****
--- 277,306 ----
  #  define TARGET_ATTRIBUTE_WEAK
  # endif
  #endif
+ 
+ /* This determines whether this target supports hidden visibility.
+    This is a weaker condition than HAVE_GAS_HIDDEN, which probes for
+    specific assembler syntax. */
+ #ifndef TARGET_SUPPORTS_HIDDEN
+ # ifdef HAVE_GAS_HIDDEN
+ #  define TARGET_SUPPORTS_HIDDEN 1
+ # else
+ #  define TARGET_SUPPORTS_HIDDEN 0
+ # endif
+ #endif
+ 
+ /* Determine whether weak symbols should be given hidden visibility by
+    default. */
+ #ifndef DEFAULT_USE_HIDDEN_WEAK
+ # define DEFAULT_USE_HIDDEN_WEAK 0
+ #endif
+ 
+ /* Determines whether we may use common symbols to represent one-only
+    semantics (a.k.a. "vague linkage"). */
+ #ifndef USE_COMMON_FOR_ONE_ONLY
+ # define USE_COMMON_FOR_ONE_ONLY 1
+ #endif
+ 
  
  /* If the target supports init_priority C++ attribute, give
     SUPPORTS_INIT_PRIORITY a nonzero value.  */
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.482
diff -p -r1.482 dwarf2out.c
*** gcc/dwarf2out.c	29 Jan 2004 08:26:24 -0000	1.482
--- gcc/dwarf2out.c	29 Jan 2004 16:00:25 -0000
*************** typedef struct cfa_loc GTY(())
*** 243,248 ****
--- 243,249 ----
  
  typedef struct dw_fde_struct GTY(())
  {
+   tree decl;
    const char *dw_fde_begin;
    const char *dw_fde_current_label;
    const char *dw_fde_end;
*************** static void def_cfa_1 (const char *, dw_
*** 391,397 ****
--- 392,400 ----
  #define FUNC_END_LABEL		"LFE"
  #endif
  
+ #ifndef FRAME_BEGIN_LABEL
  #define FRAME_BEGIN_LABEL	"Lframe"
+ #endif
  #define CIE_AFTER_SIZE_LABEL	"LSCIE"
  #define CIE_END_LABEL		"LECIE"
  #define FDE_LABEL		"LSFDE"
*************** output_call_frame_info (int for_eh)
*** 1942,1947 ****
--- 1945,1966 ----
    if (fde_table_in_use == 0)
      return;
  
+   /* If we make FDEs linkonce, we may have to emit an empty label for
+      an FDE that wouldn't otherwise be emitted.  We want to avoid
+      having an FDE kept around when the function it refers to is
+      discarded. (Example where this matters: a primary function
+      template in C++ requires EH information, but an explicit
+      specialization doesn't. */
+   if (TARGET_USES_WEAK_UNWIND_INFO
+       && ! flag_asynchronous_unwind_tables
+       && for_eh)
+     for (i = 0; i < fde_table_in_use; i++)
+       if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls)
+           && !fde_table[i].uses_eh_lsda
+ 	  && ! DECL_ONE_ONLY (fde_table[i].decl))
+ 	ASM_OUTPUT_UNWIND_LABEL (asm_out_file, fde_table[i].decl,
+ 				 /* empty */ 1);
+ 
    /* If we don't have any functions we'll want to unwind out of, don't
       emit any EH unwind information.  Note that if exceptions aren't
       enabled, we won't have collected nothrow information, and if we
*************** output_call_frame_info (int for_eh)
*** 1953,1958 ****
--- 1972,1980 ----
        for (i = 0; i < fde_table_in_use; i++)
  	if (fde_table[i].uses_eh_lsda)
  	  any_eh_needed = any_lsda_needed = true;
+         else if (TARGET_USES_WEAK_UNWIND_INFO
+ 		 && DECL_ONE_ONLY (fde_table[i].decl))
+ 	  any_eh_needed = 1;
  	else if (! fde_table[i].nothrow
  		 && ! fde_table[i].all_throwers_are_sibcalls)
  	  any_eh_needed = true;
*************** output_call_frame_info (int for_eh)
*** 2004,2010 ****
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
--- 2026,2034 ----
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = TARGET_USES_WEAK_UNWIND_INFO && !flag_hidden_weak
! 	? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1)
! 	: ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
*************** output_call_frame_info (int for_eh)
*** 2095,2103 ****
--- 2119,2130 ----
        /* Don't emit EH unwind info for leaf functions that don't need it.  */
        if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions
  	  && (fde->nothrow || fde->all_throwers_are_sibcalls)
+ 	  && (! TARGET_USES_WEAK_UNWIND_INFO || ! DECL_ONE_ONLY (fde->decl))
  	  && !fde->uses_eh_lsda)
  	continue;
  
+       ASM_OUTPUT_UNWIND_LABEL (asm_out_file, fde->decl, /* empty */ 0);
+ 
        (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
*************** output_call_frame_info (int for_eh)
*** 2113,2121 ****
  
        if (for_eh)
  	{
! 	  dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		   gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		   "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
--- 2140,2155 ----
  
        if (for_eh)
  	{
! 	  if (TARGET_USES_WEAK_UNWIND_INFO
! 	      && DECL_ONE_ONLY (fde->decl))
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER
! 					          (DECL_ASSEMBLER_NAME (fde->decl))),
! 		     "FDE initial location");
! 	  else
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		     "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
*************** dwarf2out_begin_prologue (unsigned int l
*** 2248,2253 ****
--- 2282,2288 ----
  
    /* Add the new FDE at the end of the fde_table.  */
    fde = &fde_table[fde_table_in_use++];
+   fde->decl = current_function_decl;
    fde->dw_fde_begin = xstrdup (label);
    fde->dw_fde_current_label = NULL;
    fde->dw_fde_end = NULL;
Index: gcc/flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.128
diff -p -r1.128 flags.h
*** gcc/flags.h	27 Jan 2004 12:49:30 -0000	1.128
--- gcc/flags.h	29 Jan 2004 16:00:26 -0000
*************** extern int flag_unwind_tables;
*** 505,510 ****
--- 505,515 ----
  
  extern int flag_asynchronous_unwind_tables;
  
+ /* Nonzero means that weak symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets.  */
+ 
+ extern int flag_hidden_weak;
+ 
  /* Nonzero means don't place uninitialized global data in common storage
     by default.  */
  
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.870
diff -p -r1.870 toplev.c
*** gcc/toplev.c	27 Jan 2004 12:49:30 -0000	1.870
--- gcc/toplev.c	29 Jan 2004 16:00:29 -0000
*************** unsigned local_tick;
*** 465,470 ****
--- 465,475 ----
  
  /* -f flags.  */
  
+ /* Nonzero means that weak symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets. */
+ 
+ int flag_hidden_weak = DEFAULT_USE_HIDDEN_WEAK;
+ 
  /* Nonzero means `char' should be signed.  */
  
  int flag_signed_char;
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.405
diff -p -r1.405 varasm.c
*** gcc/varasm.c	14 Jan 2004 00:49:00 -0000	1.405
--- gcc/varasm.c	29 Jan 2004 16:00:32 -0000
*************** globalize_decl (tree decl)
*** 4366,4371 ****
--- 4366,4374 ----
  	}
        return;
      }
+ #elif defined(ASM_MAKE_LABEL_LINKONCE)
+   if (DECL_ONE_ONLY (decl))
+     ASM_MAKE_LABEL_LINKONCE (asm_out_file, name);
  #endif
  
    (*targetm.asm_out.globalize_label) (asm_out_file, name);
*************** make_decl_one_only (tree decl)
*** 4490,4496 ****
  
    TREE_PUBLIC (decl) = 1;
  
!   if (TREE_CODE (decl) == VAR_DECL
        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
      DECL_COMMON (decl) = 1;
    else if (SUPPORTS_ONE_ONLY)
--- 4493,4500 ----
  
    TREE_PUBLIC (decl) = 1;
  
!   if (USE_COMMON_FOR_ONE_ONLY
!       && TREE_CODE (decl) == VAR_DECL
        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
      DECL_COMMON (decl) = 1;
    else if (SUPPORTS_ONE_ONLY)
Index: gcc/config/darwin-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin-protos.h,v
retrieving revision 1.29
diff -p -r1.29 darwin-protos.h
*** gcc/config/darwin-protos.h	10 Nov 2003 23:07:09 -0000	1.29
--- gcc/config/darwin-protos.h	29 Jan 2004 16:00:33 -0000
*************** extern void machopic_select_section (tre
*** 73,83 ****
--- 73,92 ----
  extern void machopic_select_rtx_section (enum machine_mode, rtx,
  					 unsigned HOST_WIDE_INT);
  
+ extern void darwin_unique_section (tree decl, int reloc);
+ extern void darwin_asm_named_section (const char *, unsigned int);
+ extern unsigned int darwin_section_type_flags (tree, const char *, int);
+ extern void darwin_non_lazy_pcrel (FILE *, rtx);
+ 
+ extern void darwin_output_unwind_label(FILE *, tree, int);
+ 
  extern void darwin_pragma_ignore (struct cpp_reader *);
  extern void darwin_pragma_options (struct cpp_reader *);
  extern void darwin_pragma_unused (struct cpp_reader *);
  
  extern void darwin_file_end (void);
+ 
+ extern void darwin_make_decl_one_only (tree decl);
  
  /* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o.  */
  extern void const_section (void);
Index: gcc/config/darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.c,v
retrieving revision 1.55
diff -p -r1.55 darwin.c
*** gcc/config/darwin.c	14 Nov 2003 01:47:55 -0000	1.55
--- gcc/config/darwin.c	29 Jan 2004 16:00:34 -0000
*************** machopic_finish (FILE *asm_out_file)
*** 900,909 ****
        if (! TREE_USED (temp))
  	continue;
  
-       /* If the symbol is actually defined, we don't need a stub.  */
-       if (sym_name[0] == '!' && sym_name[1] == 'T')
- 	continue;
- 
        sym_name = darwin_strip_name_encoding (sym_name);
  
        sym = alloca (strlen (sym_name) + 2);
--- 900,905 ----
*************** darwin_encode_section_info (tree decl, r
*** 1008,1013 ****
--- 1004,1010 ----
    if ((TREE_CODE (decl) == FUNCTION_DECL
         || TREE_CODE (decl) == VAR_DECL)
        && !DECL_EXTERNAL (decl)
+       && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
        && ((TREE_STATIC (decl)
  	   && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
  	  || (DECL_INITIAL (decl)
*************** update_stubs (const char *name)
*** 1159,1164 ****
--- 1156,1175 ----
  }
  
  void
+ darwin_make_decl_one_only (tree decl)
+ {
+   static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
+   static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
+ 
+   const char *sec = TREE_CODE (decl) == FUNCTION_DECL
+     ? text_section
+     : data_section;
+   TREE_PUBLIC (decl) = 1;
+   DECL_ONE_ONLY (decl) = 1;
+   DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
+ }
+ 
+ void
  machopic_select_section (tree exp, int reloc,
  			 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
  {
*************** darwin_globalize_label (FILE *stream, co
*** 1325,1330 ****
--- 1336,1438 ----
      default_globalize_label (stream, name);
  }
  
+ void
+ darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+ {
+   fprintf (asm_out_file, ".section %s\n", name);
+ }
+ 
+ unsigned int
+ darwin_section_type_flags (tree decl, const char *name, int reloc)
+ {
+   unsigned int flags = default_section_type_flags (decl, name, reloc);
+  
+   /* Weak or linkonce variables live in a writable section.  */
+   if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
+       && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
+     flags |= SECTION_WRITE;
+   
+   return flags;
+ }              
+ 
+ void 
+ darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
+ {
+   /* Darwin does not use unique sections.  However, the target's
+      unique_section hook is called for linkonce symbols.  We need
+      to set an appropriate section for such symbols. */
+   if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
+     darwin_make_decl_one_only (decl);
+ }
+ 
+ /* Emit a label for an FDE, making it global and/or weak if appropriate. 
+    The third parameter is nonzero if this is just a placeholder for an
+    FDE that we are omitting. */
+ void 
+ darwin_output_unwind_label(FILE *file, tree decl, int empty)
+ {
+   tree id = DECL_ASSEMBLER_NAME (decl)
+     ? DECL_ASSEMBLER_NAME (decl)
+     : DECL_NAME (decl);
+ 
+   const char *prefix = "_";
+   const int prefix_len = 1;
+ 
+   const char *base = IDENTIFIER_POINTER (id);
+   unsigned int base_len = IDENTIFIER_LENGTH (id);
+ 
+   const char *suffix = ".eh";
+   unsigned int suffix_len = 3;
+ 
+   int need_quotes = name_needs_quotes (base);
+   int quotes_len = need_quotes ? 2 : 0;
+ 
+   char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
+   lab[0] = '\0';
+ 
+   if (need_quotes)
+     strcat(lab, "\"");
+   strcat(lab, prefix);
+   strcat(lab, base);
+   strcat(lab, suffix);
+   if (need_quotes)
+     strcat(lab, "\"");
+ 
+   if (TREE_PUBLIC (decl))
+     fprintf (file, "%s %s\n",
+ 	     (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
+ 	      ? ".globl"
+ 	      : ".private_extern"),
+ 	     lab);
+ 
+   if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
+     fprintf (file, ".weak_definition %s\n", lab);
+ 
+   if (empty)
+     fprintf (file, "%s = 0\n", lab);
+   else
+     fprintf (file, "%s:\n", lab);
+ 
+   free (lab);
+ }
+ 
+ /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */ 
+ void
+ darwin_non_lazy_pcrel (FILE *file, rtx addr)
+ {
+   const char *str;
+   const char *nlp_name;
+ 
+   if (GET_CODE (addr) != SYMBOL_REF)
+     abort ();
+ 
+   str = darwin_strip_name_encoding (XSTR (addr, 0));
+   nlp_name = machopic_non_lazy_ptr_name (str);
+   fputs ("\t.long\t", file);
+   ASM_OUTPUT_LABELREF (file, nlp_name);
+   fputs ("-.", file);
+ }
+ 
  /* Emit an assembler directive to set visibility for a symbol.  The
     only supported visibilities are VISIBILITY_DEFAULT and
     VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
*************** void
*** 1361,1368 ****
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   const char *p = lab1 + (lab1[0] == '*');
!   int islocaldiff = (p[0] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
--- 1469,1476 ----
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
! 		     && lab2[0] == '*' && lab2[1] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.65
diff -p -r1.65 darwin.h
*** gcc/config/darwin.h	26 Dec 2003 19:13:35 -0000	1.65
--- gcc/config/darwin.h	29 Jan 2004 16:00:34 -0000
*************** do { text_section ();							\
*** 310,315 ****
--- 310,362 ----
  	      "\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", "" , N_SO);	\
     } while (0)
  
+ /* Making a symbols weak on Darwin requires more than just setting DECL_WEAK. */
+ #define MAKE_DECL_ONE_ONLY(DECL) darwin_make_decl_one_only (DECL)
+ 
+ /* Representation of linkonce symbols for the MACH-O assembler. Linkonce
+    symbols must be given a special section *and* must be preceded by a 
+    special assembler directive. */
+ #define ASM_MAKE_LABEL_LINKONCE(FILE,  NAME)                            \
+  do { const char* _x = (NAME); if (!!strncmp (_x, "_OBJC_", 6)) {	\
+   fputs (".weak_definition ", FILE); assemble_name (FILE, _x);		\
+   fputs ("\n", FILE); }} while (0)
+ 
+ /* We support hidden visibility */
+ #undef TARGET_SUPPORTS_HIDDEN
+ #define TARGET_SUPPORTS_HIDDEN 1
+ 
+ /* Weak symbols are not hidden by default (can be overridden with
+    -fhidden-weak) */
+ #undef DEFAULT_USE_HIDDEN_WEAK
+ #define DEFAULT_USE_HIDDEN_WEAK 0
+ 
+ /* The Darwin linker imposes two limitations on common symbols: they 
+    can't have hidden visibility, and they can't appear in dylibs.  As
+    a consequence, we should never use common symbols to represent 
+    vague linkage. */
+ #undef USE_COMMON_FOR_ONE_ONLY
+ #define USE_COMMON_FOR_ONE_ONLY 0
+ 
+ /* The Darwin linker doesn't like coalesced symbols to appear in a
+    static archive's table of contents, because it can't handle
+    duplicate entries in a TOC. */
+ #undef TARGET_WEAK_NO_TOC
+ #define TARGET_WEAK_NO_TOC 1
+ 
+ /* We make exception information linkonce. */
+ #undef TARGET_USES_WEAK_UNWIND_INFO
+ #define TARGET_USES_WEAK_UNWIND_INFO 1
+ 
+ /* We need to use a nonlocal label for the start of an EH frame: the
+    Darwin linker requires that a coalesced section start with a label. */
+ #undef FRAME_BEGIN_LABEL
+ #define FRAME_BEGIN_LABEL "EH_frame"
+ 
+ /* Emit a label for the FDE corresponding to DECL.  EMPTY means 
+    emit a label for an empty FDE. */
+ #define ASM_OUTPUT_UNWIND_LABEL(FILE, DECL, EMPTY) \
+   darwin_output_unwind_label ((FILE), (DECL), (EMPTY))
+ 
  /* Our profiling scheme doesn't LP labels and counter words.  */
  
  #define NO_PROFILE_COUNTERS	1
*************** do { text_section ();							\
*** 361,370 ****
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if ((TREE_STATIC (DECL)						\
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!         || DECL_INITIAL (DECL))						\
!       machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
--- 408,418 ----
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))                   \
!       if ((TREE_STATIC (DECL)						\
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!           || DECL_INITIAL (DECL))					\
!         machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
*************** do { text_section ();							\
*** 381,398 ****
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if ((TREE_STATIC (DECL)                                             \
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
!         || DECL_INITIAL (DECL))                                         \
!       machopic_define_name (xname);                                     \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
-     /* Avoid generating stubs for functions we've just defined by	\
-        outputting any required stub name label now.  */			\
-     machopic_output_possible_stub_label (FILE, xname);			\
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
--- 429,444 ----
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))			\
!       if ((TREE_STATIC (DECL)                                           \
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))             \
!           || DECL_INITIAL (DECL))                                       \
!         machopic_define_name (xname);                                   \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
*************** SECTION_FUNCTION (darwin_exception_secti
*** 640,646 ****
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section __TEXT,__eh_frame", 0)	\
  							\
  static void					\
  objc_section_init (void)			\
--- 686,692 ----
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section " EH_FRAME_SECTION_NAME ",__eh_frame" EH_FRAME_SECTION_ATTR, 0)  \
  							\
  static void					\
  objc_section_init (void)			\
*************** objc_section_init (void)			\
*** 681,686 ****
--- 727,736 ----
  #define TARGET_ASM_SELECT_SECTION machopic_select_section
  #undef	TARGET_ASM_SELECT_RTX_SECTION
  #define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
+ #undef  TARGET_ASM_UNIQUE_SECTION
+ #define TARGET_ASM_UNIQUE_SECTION darwin_unique_section
+ 
+ 
  
  #define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME)			\
      do {								\
*************** enum machopic_addr_class {
*** 808,813 ****
--- 858,866 ----
  
  #define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
  
+ #define EH_FRAME_SECTION_NAME   "__TEXT"
+ #define EH_FRAME_SECTION_ATTR ",coalesced,no_toc+strip_static_syms"
+ 
  #undef ASM_PREFERRED_EH_DATA_FORMAT
  #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)  \
    (((CODE) == 2 && (GLOBAL) == 1) \
*************** enum machopic_addr_class {
*** 817,823 ****
--- 870,888 ----
  #define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
    darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
  
+ #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE)	\
+       if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) {				\
+ 	darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR);					\
+ 	goto DONE;									\
+       }
+ 
+ 
  #define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
+ 
+ #undef TARGET_ASM_NAMED_SECTION
+ #define TARGET_ASM_NAMED_SECTION darwin_asm_named_section
+ #undef TARGET_SECTION_TYPE_FLAGS
+ #define TARGET_SECTION_TYPE_FLAGS darwin_section_type_flags
  
  #define DARWIN_REGISTER_TARGET_PRAGMAS()			\
    do {								\
Index: gcc/cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3917
diff -p -r1.3917 ChangeLog
*** gcc/cp/ChangeLog	29 Jan 2004 04:23:37 -0000	1.3917
--- gcc/cp/ChangeLog	29 Jan 2004 16:00:35 -0000
***************
*** 1,3 ****
--- 1,17 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 
+ 	* decl2.c (comdat_linkage): Set visibility of weak symbols to
+ 	VISIBLITY_HIDDEN if user sets the appropriate flag.
+ 	(maybe_make_one_only): Ditto.
+ 	(maybe_emit_vtables): If weak symbols are hidden, be more
+ 	cautious about making vtables weak.
+ 	* method.c (make_thunk): If weak symbols are hidden, be more
+ 	cautious about making thunks weak.
+ 	(use_thunk): Ditto.
+ 	* pt.c (do_type_instantiation): On systems where weak symbols
+ 	don't go in a static archive's TOC, explicit instantiation of a
+ 	class must imply *explicit* instantiation of its memeber.
+ 	
  2004-01-28  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
  
  	* parser.c (cp_parser_template_id): Parse tentatively `[:' after a 
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.697
diff -p -r1.697 decl2.c
*** gcc/cp/decl2.c	26 Jan 2004 17:41:50 -0000	1.697
--- gcc/cp/decl2.c	29 Jan 2004 16:00:38 -0000
*************** void
*** 1359,1365 ****
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     make_decl_one_only (decl);
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
--- 1359,1369 ----
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     {
!       make_decl_one_only (decl);
!       if (flag_hidden_weak)
! 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
!     }
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
*************** maybe_make_one_only (tree decl)
*** 1426,1431 ****
--- 1430,1437 ----
       because their DECL_INITIAL may not have been set properly yet.  */
  
    make_decl_one_only (decl);
+   if (flag_hidden_weak)
+     DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  
    if (TREE_CODE (decl) == VAR_DECL)
      {
*************** maybe_emit_vtables (tree ctype)
*** 1561,1566 ****
--- 1567,1573 ----
    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)
*** 1591,1596 ****
--- 1598,1624 ----
    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: on systems where we don't have weak symbols
+      (obviously), and if weak symbols are given hidden visibility.  In
+      the latter case we make vtables weak only in cases where they
+      really will be emitted in multiple translation units, not in the
+      more common case where we're emitting the vtable in the
+      translation unit containing the definition of a noninline key
+      method. */
+   if (flag_weak && !flag_hidden_weak)
+     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)
*** 1637,1644 ****
  	  DECL_IGNORED_P (vtbl) = 1;
  	}
  
!       /* Always make vtables weak.  */
!       if (flag_weak)
  	comdat_linkage (vtbl);
  
        rest_of_decl_compilation (vtbl, NULL, 1, 1);
--- 1665,1672 ----
  	  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/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.275
diff -p -r1.275 method.c
*** gcc/cp/method.c	2 Jan 2004 15:57:16 -0000	1.275
--- gcc/cp/method.c	29 Jan 2004 16:00:38 -0000
*************** make_thunk (tree function, bool this_adj
*** 153,160 ****
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
    if (flag_weak)
!     comdat_linkage (thunk);
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
--- 153,167 ----
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
+ 
+   /* Always make thunks weak.  Or at least *almost* always.  If weak
+      symbols may be given hidden visibility, we have to be more careful. */
    if (flag_weak)
!     if (!flag_hidden_weak
! 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
! 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
!       comdat_linkage (thunk);
! 
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 390,395 ****
--- 397,407 ----
       rewrite.  */
    TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
    DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
+   if (flag_weak)
+     if (!flag_hidden_weak
+ 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
+ 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
+       comdat_linkage (thunk_fndecl);
  
    if (flag_syntax_only)
      {
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.821
diff -p -r1.821 pt.c
*** gcc/cp/pt.c	26 Jan 2004 17:41:50 -0000	1.821
--- gcc/cp/pt.c	29 Jan 2004 16:00:46 -0000
*************** do_type_instantiation (tree t, tree stor
*** 10576,10581 ****
--- 10576,10582 ----
    int extern_p = 0;
    int nomem_p = 0;
    int static_p = 0;
+   int previous_instantiation_extern_p = 0;
  
    if (TREE_CODE (t) == TYPE_DECL)
      t = TREE_TYPE (t);
*************** do_type_instantiation (tree t, tree stor
*** 10637,10647 ****
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation
! 	 was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
! 	 are we already got marked as an explicit instantiation because of the
! 	 repo file.  All these cases are OK.  */
!       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
--- 10638,10653 ----
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
! 	 instantiation was `extern'.  If EXTERN_P then the second is.
! 	 If -frepo, chances are we already got marked as an explicit
! 	 instantiation because of the repo file.  All these cases are
! 	 OK.  */
! 
!       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
! 
!       if (!previous_instantiation_extern_p && !extern_p
! 	  && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
*************** do_type_instantiation (tree t, tree stor
*** 10658,10663 ****
--- 10664,10670 ----
  
    {
      tree tmp;
+     int explicitly_instantiate_members = 0;
  
      /* In contrast to implicit instantiation, where only the
         declarations, and not the definitions, of members are
*************** do_type_instantiation (tree t, tree stor
*** 10676,10701 ****
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  */
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    mark_decl_instantiated (tmp, extern_p);
! 	    repo_template_instantiated (tmp, extern_p);
! 	    if (! extern_p)
! 	      instantiate_decl (tmp, /*defer_ok=*/1);
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  mark_decl_instantiated (tmp, extern_p);
! 	  repo_template_instantiated (tmp, extern_p);
! 	  if (! extern_p)
! 	    instantiate_decl (tmp, /*defer_ok=*/1);
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
--- 10683,10728 ----
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  Exception:
!        on some targets (e.g. Darwin), weak symbols do not get put in 
!        a static archive's TOC.  The problematic case is if we're doing
!        a non-extern explicit instantiation of an extern template: we
!        have to put member functions in the TOC in that case, or we'll
!        get unresolved symbols at link time. */
! 
!     explicitly_instantiate_members =
!       TARGET_WEAK_NO_TOC
!       && previous_instantiation_extern_p && ! extern_p
!       && ! TYPE_FOR_JAVA (t);
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    if (explicitly_instantiate_members)
! 	      do_decl_instantiation (tmp, NULL_TREE);
! 	    else
! 	      {
! 		mark_decl_instantiated (tmp, extern_p);
! 		repo_template_instantiated (tmp, extern_p);
! 		if (! extern_p)
! 		  instantiate_decl (tmp, /*defer_ok=*/1);
! 	      }
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  if (explicitly_instantiate_members)
! 	    do_decl_instantiation (tmp, NULL_TREE);
! 	  else
! 	    {
! 	      mark_decl_instantiated (tmp, extern_p);
! 	      repo_template_instantiated (tmp, extern_p);
! 	      if (! extern_p)
! 		instantiate_decl (tmp, /*defer_ok=*/1);
! 	    }
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
Index: libffi/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libffi/ChangeLog,v
retrieving revision 1.157
diff -p -r1.157 ChangeLog
*** libffi/ChangeLog	25 Jan 2004 06:58:33 -0000	1.157
--- libffi/ChangeLog	29 Jan 2004 16:00:54 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 	* src/powerpc/darwin.S: Change EH information in assembly glue to
+ 	match EH format changes in the compiler.
+ 	* src/powerpc/darwin_closure.S: Ditto.
+ 	
  2004-01-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
  
  	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
Index: libffi/src/powerpc/darwin.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin.S,v
retrieving revision 1.7
diff -p -r1.7 darwin.S
*** libffi/src/powerpc/darwin.S	21 Oct 2003 19:01:56 -0000	1.7
--- libffi/src/powerpc/darwin.S	29 Jan 2004 16:00:54 -0000
*************** _ffi_call_AIX:
*** 162,169 ****
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 162,169 ----
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 173,191 ****
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte   0x1     ; uleb128 0x1; Augmentation size
! 	.byte   0x10    ; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
--- 173,192 ----
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_call_DARWIN.eh
+ _ffi_call_DARWIN.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.long	LASFDE1-EH_frame1 ; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
Index: libffi/src/powerpc/darwin_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin_closure.S,v
retrieving revision 1.6
diff -p -r1.6 darwin_closure.S
*** libffi/src/powerpc/darwin_closure.S	18 Sep 2003 19:35:46 -0000	1.6
--- libffi/src/powerpc/darwin_closure.S	29 Jan 2004 16:00:54 -0000
*************** Lfinish:
*** 234,241 ****
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 234,241 ----
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 246,264 ****
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x10	; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range
--- 246,265 ----
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_closure_ASM.eh
+ _ffi_closure_ASM.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.long	LASFDE1-EH_frame1	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range

[-- Attachment #3: Type: text/plain, Size: 2 bytes --]




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

* [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-29 17:42 [Darwin] Patch: enable linkonce support for Darwin Matt Austern
@ 2004-01-30 16:53 ` Matt Austern
  2004-01-31  0:05   ` Richard Henderson
  0 siblings, 1 reply; 17+ messages in thread
From: Matt Austern @ 2004-01-30 16:53 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 7289 bytes --]

On Jan 29, 2004, at 8:06 AM, Matt Austern wrote:

This patch enables linkonce support, a.k.a. vague linkage, a.k.a 
comdat, for Darwin.  It fixes a bunch of test case failures from g++.dg 
and g++.old-deja.  (init/init-ref4.C, parse/attr-ctor1.C, 
parse/constant4.C, template/non-dependent2.C, 
template/non-dependent3.C, g++.other/comdat3.C, g++.other/mangle3.C, 
g++.pt/static3.C, g++.pt/static6.C) It also fixes 
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11026, which is a P2 bug.

Testing: bootstrapped (C, C++, Java) on OS X 10.3, no regressions in 
the C, C++, or libstdc++ testsuites.

This new and improved patch includes documentation for -fhidden-weak 
and for the new target macros, and test cases for -fhidden-weak.

The explanation of the patch is pretty much the same as in the first 
version, but I'm reposting it here so people don't have to go back 
through the archives.  As before, it's pretty easy to understand in 
terms of Darwin linker features.

Vague linkage on Darwin uses a feature called coalescing, which is sort 
of like ELF weak symbols and sort of like GNU linkonce sections except 
that it's not all that much like either of them.  A coalesced symbol 
must be marked with the .weak_definition directive and must also appear 
in a section that is marked with the "coalesced" flag.  These aren't 
like GNU linkonce sections because we have many symbols per coalesced 
section, not one section per symbol.  All coalesced function 
definitions, for example, go in __TEXT,__textcoal_nt.  References to 
coalesced symbols must be indirect, even if the compiler thinks it sees 
a definition of a coalesced symbol in the same translation unit as the 
use.  Coalescing is only for defined symbols, and only applies to 
symbols with global or private extern scope.

The Darwin linker doesn't have a notion of subsections, so coalescing 
simply works at the level of things between one nonlocal symbol (a 
nonlocal symbol starts with something other than "L") and the next.  A 
coalesced section must begin with a nonlocal symbol.

Exceptions are an annoying problem.  Here's the problem scenerio: 
suppose an FDE in a .o refers to local symbols in a coalesced function 
from that same .o, and now suppose that particular copy of the 
coalesced function gets discarded by the linker.  In that case, the 
dangling reference will cause the Darwin linker to die horribly.  The 
solution we came up with, which Apple has been using in our locally 
modified compiler for two years, is to coalesce FDEs too.  We give 
every FDE its own symbol (the name we choose is <foo>.eh, where <foo> 
is the assembler name of the function the FDE corresponds to), so that 
the FDEs too are coalesced.  We make sure that a function and its FDE 
always have the same scope and visibility; the idea is that if the 
linker discards a coalesced function, it will also discard the 
corresponding coalesced FDE.  There's one little subtlety involving 
implicit instantiations that have FDEs and explicit instantiations that 
don't, and we solve that by sometimes generating dummy FDE labels.   
This is admittedly a crude scheme; you can think of it as "poor man's 
group COMDAT".  It's probably the best we can do given the Darwin 
linker, though, and Apple has shown that it can actually work.

To support all this exception machinery I put in a link from 
dw_fde_struct back to the associated decl (we'll need that for other 
targets, anyway, when and if we move to ELF group COMDAT), and I 
introduced a new target macro, ASM_OUTPUT_UNWIND_LABEL, to give FDEs 
their labels.  Everywhere but Darwin, that macro does nothing.

Two minor quirks of the Darwin linker that we have to accommodate.

First quirk: coalesced symbols can't be put in a static archive's table 
of contents.  If the linker sees a static archive with duplicate TOC 
entries, it will give an unfriendly warning and then behave 
unpredictably.  That's why (as you'll see if you look in the darwin.c 
section of my patch) the __TEXT,__textcoal_nt section is given the 
"no_toc" flag.  OK, what's the consequence of this?  Since you'll never 
find a coalesced symbol from the TOC, you have to make sure a symbol 
will only be marked as coalesced if it's something that can be 
regenerated in every translation unit where it's needed.  There's 
exactly one obscure corner case where it matters: explicit 
instantiation of a class template that's marked as "extern".  The 
question is whether explicit instantiation of a class template triggers 
explicit or implicit instantiation of its member functions.  As it 
stands, the compiler does an implicit instantiation (with a note in the 
comments saying that the standard doesn't say which one it should do).  
My patch keeps that behavior in general, but makes it an explicit 
instantiation, thus something that will appear in the TOC, for Darwin 
in the special case where we're explicitly instantiating a previously 
extern template.  I introduced a new target macro,  TARGET_WEAK_NO_TOC, 
to control this behavior.

Second quirk: Common is bad news.  Common symbols in Darwin can't have 
hidden visibility and can't be exported from dylibs.   The second is 
deliberate and the first is a bug, but both of them are things we have 
to deal with.  So we really just shouldn't ever use common to implement 
vague linkage, we should always use coalescing instead.  I introduced 
another target macro, USE_COMMON_FOR_ONE_ONLY, so we can tell the 
compiler about targets where common is a poor choice for representing 
vague linkage.  (Again: this is not the same thing as -fno-common.  
Common is fine in its place, just not for vague linkage.)

Finally, one new user-visible feature: -fhidden-weak.  This flag makes 
the compiler automatically give hidden visibility to symbols that have 
vague linkage.  This feature has proved useful in Apple compilers, 
because sometimes exporting coalesced symbols from dylibs interacts 
poorly with some of our more complicated linker features.  I also have 
the sense from C++ standardization committee discussions that, if the 
committee ever standardizes dynamic libraries, something like this is 
the direction things are likely to go.  I haven't made -fhidden-weak 
the default on any platform, not even Darwin, but I've left in the 
machinery so it can be made the default.   One more target macro 
associated with this: TARGET_SUPPORTS_HIDDEN.  No, HAVE_GAS_HIDDEN 
doesn't cover this; it's a slightly weaker condition.

Potentially questionable decisions.  First, I'm keying this off 
DECL_ONE_ONLY, not DECL_WEAK.  I don't have strong feelings about this, 
but I think it's a slightly better choice.  DECL_WEAK has just a little 
too much baggage associated with it, and there are too many places in 
the back end that think that DECL_WEAK means all of the things that 
weak symbols mean on ELF.  Second, I've introduced target macros and 
not target hooks.  Again I don't have a strong preference, but (this is 
subjective) in my opinion target macros were more consistent with 
existing style.  The sorts of things I'm doing here seemed more like 
the things people are currently doing with target macros than like the 
things people are currently doing with hooks.

Here's the patch.  OK to commit to mainline?

			--Matt


[-- Attachment #2: weak-darwin-2.txt --]
[-- Type: text/plain, Size: 66382 bytes --]

Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.2556
diff -p -r2.2556 ChangeLog
*** gcc/ChangeLog	29 Jan 2004 18:52:12 -0000	2.2556
--- gcc/ChangeLog	30 Jan 2004 06:34:15 -0000
***************
*** 1,3 ****
--- 1,59 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 
+ 	* c-opts.c (c_common_handle_option): Add -fhidden-weak option.
+ 	* c.opt: Ditto.
+ 	* flags.h (flag_hidden_weak): flag corresponding to -fhidden-weak.
+ 	* toplev.c (flag_hidden_weak): Ditto.
+ 	* default.h (ASM_OUTPUT_UNWIND_LABEL): New target macro.
+ 	(TARGET_WEAK_NO_TOC): New target macro.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): New target macro.
+ 	(TARGET_SUPPORTS_HIDDEN): New target macro.
+ 	(USE_COMMON_FOR_ONE_ONLY): New target macro.
+ 	* dwarf2out.c (struct dw_fde_struct): Add field for function decl
+ 	that corresponds to this FDE.
+ 	(FRAME_BEGIN_LABEL): Allow target to override default label.
+ 	(output_call_frame_info): If FDEs are linknonce, then use extra
+ 	indirection for FDE encoding, output a label for each FDE, and 
+ 	output an empty label for each function without an FDE.
+ 	(dwarf2out_begin_prologue): Set up decl field when creating an FDE.
+ 	* varasm.c (globalize_decl): Call ASM_MAKE_LABEL_LINKONCE for
+ 	decls with DECL_ONE_ONLY set, if that macro is defined.
+ 	(make_decl_one_only): On systems where USE_COMMON_FOR_ONE_ONLY is
+ 	false, don't use DECL_COMMON, instead use DECL_ONE_ONLY.
+ 	* config/darwin-protos.h (darwin_unique_section): Declare.
+ 	(darwin_asm_named_section): Ditto.
+ 	(darwin_section_type_flags): Ditto.
+ 	(darwin_non_lazy_pcrel): Ditto.
+ 	(darwin_output_unwind_label): Ditto.
+ 	(darwin_make_decl_one_only): Ditto.
+ 	* config/darwin.c (machopic_finish): Get rid of tweak that
+ 	eliminate stubs for symbols that are defined.
+ 	(darwin_encode_section_info): Don't treat weak functiosn as defined.
+ 	(darwin_make_decl_one_only): Define.
+ 	(darwin_asm_named_section): Ditto.
+ 	(darwin_section_type_flags): Ditto.
+ 	(darwin_unique_section): Ditto.
+ 	(darwin_output_unwind_label): Ditto.
+ 	(darwin_non_lazy_pcrel): Ditto.
+ 	(darwin_asm_output_dwarf_delta): Difference between two labels is
+ 	local only if both labels are local.
+ 	* config/darwin.h (MAKE_DECL_ONE_ONLY): Define.
+ 	(ASM_MAKE_LABEL_LINKONCE): Ditto.
+ 	(TARGET_SUPPORTS_HIDDEN): Ditto.
+ 	(USE_COMMON_FOR_ONE_ONLY): Ditto.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): Ditto.
+ 	(FRAME_BEGIN_LABEL): Ditto.
+ 	(ASM_OUTPUT_UNWIND_LABEL): Ditto.
+ 	(ASM_DECLARE_OBJECT_NAME): Make references to weak symbols indirect.
+ 	(ASM_DECLARE_FUNCTION_NAME): Ditto.
+ 	(darwin_eh_frame_section): Give __eh_frame section the coalesced flag.
+ 	(TARGET_ASM_UNIQUE_SECTION): Define.
+ 	(EH_FRAME_SECTION_NAME): Define.
+ 	(EH_FRAME_SECTION_ATTR): Ditto.
+ 	(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Ditto.
+ 	(TARGET_ASM_NAMED_SECTION): Ditto.
+ 	(TARGET_SECTION_TYPE_FLAGS): Ditto.
+ 	
  2004-01-29  Jakub Jelinek  <jakub@redhat.com>
  
  	* emit-rtl.c (change_address): Use XEXP (memref, 0) instead
Index: gcc/c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.98
diff -p -r1.98 c-opts.c
*** gcc/c-opts.c	21 Jan 2004 20:39:51 -0000	1.98
--- gcc/c-opts.c	30 Jan 2004 06:34:16 -0000
*************** c_common_handle_option (size_t scode, co
*** 916,921 ****
--- 916,932 ----
        flag_weak = value;
        break;
  
+     case OPT_fhidden_weak:
+       flag_hidden_weak = value;
+ #if !TARGET_SUPPORTS_HIDDEN
+       if (value)
+ 	{
+ 	  warning ("-fhidden-weak not supported for this target, ignored");
+ 	  flag_hidden_weak = 0;
+ 	}
+ #endif
+       break;
+ 
      case OPT_fzero_link:
        flag_zero_link = value;
        break;
Index: gcc/c.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c.opt,v
retrieving revision 1.17
diff -p -r1.17 c.opt
*** gcc/c.opt	25 Sep 2003 01:25:50 -0000	1.17
--- gcc/c.opt	30 Jan 2004 06:34:16 -0000
*************** fweak
*** 666,671 ****
--- 666,675 ----
  C++ ObjC++
  Emit common-like symbols as weak symbols
  
+ fhidden-weak
+ C++ ObjC++
+ Give weak symbols hidden visibility on targets that support it
+ 
  fwide-exec-charset=
  C ObjC C++ ObjC++ Joined RejectNegative
  -fwide-exec-charset=<cset>	Convert all wide strings and character constants to character set <cset>
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.126
diff -p -r1.126 defaults.h
*** gcc/defaults.h	21 Jan 2004 20:39:53 -0000	1.126
--- gcc/defaults.h	30 Jan 2004 06:34:17 -0000
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 219,224 ****
--- 219,232 ----
  #endif
  #endif
  
+ /* How to emit a nonlocal label for FDEs.  Default is to do nothing,
+    because most targets don't need such labels. The meaning of the 
+    first two parameters is obvious.  The third is a boolean: true if
+    this is a placeholder label for an omitted FDE. */
+ #ifndef ASM_OUTPUT_UNWIND_LABEL
+ #define ASM_OUTPUT_UNWIND_LABEL(FILE, DECL, EMPTY) do { } while(0)
+ #endif
+ 
  /* This determines whether or not we support weak symbols.  */
  #ifndef SUPPORTS_WEAK
  #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 237,242 ****
--- 245,262 ----
  #endif
  #endif
  
+ /* Determines whether symbols with link-once semantics should be given
+    special treatments so that they don't get put in the table of
+    contents of a static archive. */
+ #ifndef TARGET_WEAK_NO_TOC
+ # define TARGET_WEAK_NO_TOC 0
+ #endif
+ 
+ /* This determines whether or not we need linkonce unwind information */
+ #ifndef TARGET_USES_WEAK_UNWIND_INFO
+ #define TARGET_USES_WEAK_UNWIND_INFO 0
+ #endif
+ 
  /* By default, there is no prefix on user-defined symbols.  */
  #ifndef USER_LABEL_PREFIX
  #define USER_LABEL_PREFIX ""
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 257,262 ****
--- 277,300 ----
  #  define TARGET_ATTRIBUTE_WEAK
  # endif
  #endif
+ 
+ /* This determines whether this target supports hidden visibility.
+    This is a weaker condition than HAVE_GAS_HIDDEN, which probes for
+    specific assembler syntax. */
+ #ifndef TARGET_SUPPORTS_HIDDEN
+ # ifdef HAVE_GAS_HIDDEN
+ #  define TARGET_SUPPORTS_HIDDEN 1
+ # else
+ #  define TARGET_SUPPORTS_HIDDEN 0
+ # endif
+ #endif
+ 
+ /* Determines whether we may use common symbols to represent one-only
+    semantics (a.k.a. "vague linkage"). */
+ #ifndef USE_COMMON_FOR_ONE_ONLY
+ # define USE_COMMON_FOR_ONE_ONLY 1
+ #endif
+ 
  
  /* If the target supports init_priority C++ attribute, give
     SUPPORTS_INIT_PRIORITY a nonzero value.  */
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.483
diff -p -r1.483 dwarf2out.c
*** gcc/dwarf2out.c	29 Jan 2004 18:42:56 -0000	1.483
--- gcc/dwarf2out.c	30 Jan 2004 06:34:24 -0000
*************** typedef struct cfa_loc GTY(())
*** 243,248 ****
--- 243,249 ----
  
  typedef struct dw_fde_struct GTY(())
  {
+   tree decl;
    const char *dw_fde_begin;
    const char *dw_fde_current_label;
    const char *dw_fde_end;
*************** static void def_cfa_1 (const char *, dw_
*** 391,397 ****
--- 392,400 ----
  #define FUNC_END_LABEL		"LFE"
  #endif
  
+ #ifndef FRAME_BEGIN_LABEL
  #define FRAME_BEGIN_LABEL	"Lframe"
+ #endif
  #define CIE_AFTER_SIZE_LABEL	"LSCIE"
  #define CIE_END_LABEL		"LECIE"
  #define FDE_LABEL		"LSFDE"
*************** output_call_frame_info (int for_eh)
*** 1942,1947 ****
--- 1945,1966 ----
    if (fde_table_in_use == 0)
      return;
  
+   /* If we make FDEs linkonce, we may have to emit an empty label for
+      an FDE that wouldn't otherwise be emitted.  We want to avoid
+      having an FDE kept around when the function it refers to is
+      discarded. (Example where this matters: a primary function
+      template in C++ requires EH information, but an explicit
+      specialization doesn't. */
+   if (TARGET_USES_WEAK_UNWIND_INFO
+       && ! flag_asynchronous_unwind_tables
+       && for_eh)
+     for (i = 0; i < fde_table_in_use; i++)
+       if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls)
+           && !fde_table[i].uses_eh_lsda
+ 	  && ! DECL_ONE_ONLY (fde_table[i].decl))
+ 	ASM_OUTPUT_UNWIND_LABEL (asm_out_file, fde_table[i].decl,
+ 				 /* empty */ 1);
+ 
    /* If we don't have any functions we'll want to unwind out of, don't
       emit any EH unwind information.  Note that if exceptions aren't
       enabled, we won't have collected nothrow information, and if we
*************** output_call_frame_info (int for_eh)
*** 1953,1958 ****
--- 1972,1980 ----
        for (i = 0; i < fde_table_in_use; i++)
  	if (fde_table[i].uses_eh_lsda)
  	  any_eh_needed = any_lsda_needed = true;
+         else if (TARGET_USES_WEAK_UNWIND_INFO
+ 		 && DECL_ONE_ONLY (fde_table[i].decl))
+ 	  any_eh_needed = 1;
  	else if (! fde_table[i].nothrow
  		 && ! fde_table[i].all_throwers_are_sibcalls)
  	  any_eh_needed = true;
*************** output_call_frame_info (int for_eh)
*** 2004,2010 ****
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
--- 2026,2034 ----
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = TARGET_USES_WEAK_UNWIND_INFO && !flag_hidden_weak
! 	? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1)
! 	: ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
*************** output_call_frame_info (int for_eh)
*** 2095,2103 ****
--- 2119,2130 ----
        /* Don't emit EH unwind info for leaf functions that don't need it.  */
        if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions
  	  && (fde->nothrow || fde->all_throwers_are_sibcalls)
+ 	  && (! TARGET_USES_WEAK_UNWIND_INFO || ! DECL_ONE_ONLY (fde->decl))
  	  && !fde->uses_eh_lsda)
  	continue;
  
+       ASM_OUTPUT_UNWIND_LABEL (asm_out_file, fde->decl, /* empty */ 0);
+ 
        (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
*************** output_call_frame_info (int for_eh)
*** 2113,2121 ****
  
        if (for_eh)
  	{
! 	  dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		   gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		   "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
--- 2140,2155 ----
  
        if (for_eh)
  	{
! 	  if (TARGET_USES_WEAK_UNWIND_INFO
! 	      && DECL_ONE_ONLY (fde->decl))
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER
! 					          (DECL_ASSEMBLER_NAME (fde->decl))),
! 		     "FDE initial location");
! 	  else
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		     "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
*************** dwarf2out_begin_prologue (unsigned int l
*** 2248,2253 ****
--- 2282,2288 ----
  
    /* Add the new FDE at the end of the fde_table.  */
    fde = &fde_table[fde_table_in_use++];
+   fde->decl = current_function_decl;
    fde->dw_fde_begin = xstrdup (label);
    fde->dw_fde_current_label = NULL;
    fde->dw_fde_end = NULL;
Index: gcc/flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.128
diff -p -r1.128 flags.h
*** gcc/flags.h	27 Jan 2004 12:49:30 -0000	1.128
--- gcc/flags.h	30 Jan 2004 06:34:25 -0000
*************** extern int flag_unwind_tables;
*** 505,510 ****
--- 505,515 ----
  
  extern int flag_asynchronous_unwind_tables;
  
+ /* Nonzero means that weak symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets.  */
+ 
+ extern int flag_hidden_weak;
+ 
  /* Nonzero means don't place uninitialized global data in common storage
     by default.  */
  
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.870
diff -p -r1.870 toplev.c
*** gcc/toplev.c	27 Jan 2004 12:49:30 -0000	1.870
--- gcc/toplev.c	30 Jan 2004 06:34:28 -0000
*************** unsigned local_tick;
*** 465,470 ****
--- 465,475 ----
  
  /* -f flags.  */
  
+ /* Nonzero means that weak symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets. */
+ 
+ int flag_hidden_weak = 0;
+ 
  /* Nonzero means `char' should be signed.  */
  
  int flag_signed_char;
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.405
diff -p -r1.405 varasm.c
*** gcc/varasm.c	14 Jan 2004 00:49:00 -0000	1.405
--- gcc/varasm.c	30 Jan 2004 06:34:31 -0000
*************** globalize_decl (tree decl)
*** 4366,4371 ****
--- 4366,4374 ----
  	}
        return;
      }
+ #elif defined(ASM_MAKE_LABEL_LINKONCE)
+   if (DECL_ONE_ONLY (decl))
+     ASM_MAKE_LABEL_LINKONCE (asm_out_file, name);
  #endif
  
    (*targetm.asm_out.globalize_label) (asm_out_file, name);
*************** make_decl_one_only (tree decl)
*** 4490,4496 ****
  
    TREE_PUBLIC (decl) = 1;
  
!   if (TREE_CODE (decl) == VAR_DECL
        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
      DECL_COMMON (decl) = 1;
    else if (SUPPORTS_ONE_ONLY)
--- 4493,4500 ----
  
    TREE_PUBLIC (decl) = 1;
  
!   if (USE_COMMON_FOR_ONE_ONLY
!       && TREE_CODE (decl) == VAR_DECL
        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
      DECL_COMMON (decl) = 1;
    else if (SUPPORTS_ONE_ONLY)
Index: gcc/config/darwin-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin-protos.h,v
retrieving revision 1.29
diff -p -r1.29 darwin-protos.h
*** gcc/config/darwin-protos.h	10 Nov 2003 23:07:09 -0000	1.29
--- gcc/config/darwin-protos.h	30 Jan 2004 06:34:32 -0000
*************** extern void machopic_select_section (tre
*** 73,83 ****
--- 73,92 ----
  extern void machopic_select_rtx_section (enum machine_mode, rtx,
  					 unsigned HOST_WIDE_INT);
  
+ extern void darwin_unique_section (tree decl, int reloc);
+ extern void darwin_asm_named_section (const char *, unsigned int);
+ extern unsigned int darwin_section_type_flags (tree, const char *, int);
+ extern void darwin_non_lazy_pcrel (FILE *, rtx);
+ 
+ extern void darwin_output_unwind_label(FILE *, tree, int);
+ 
  extern void darwin_pragma_ignore (struct cpp_reader *);
  extern void darwin_pragma_options (struct cpp_reader *);
  extern void darwin_pragma_unused (struct cpp_reader *);
  
  extern void darwin_file_end (void);
+ 
+ extern void darwin_make_decl_one_only (tree decl);
  
  /* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o.  */
  extern void const_section (void);
Index: gcc/config/darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.c,v
retrieving revision 1.55
diff -p -r1.55 darwin.c
*** gcc/config/darwin.c	14 Nov 2003 01:47:55 -0000	1.55
--- gcc/config/darwin.c	30 Jan 2004 06:34:33 -0000
*************** machopic_finish (FILE *asm_out_file)
*** 900,909 ****
        if (! TREE_USED (temp))
  	continue;
  
-       /* If the symbol is actually defined, we don't need a stub.  */
-       if (sym_name[0] == '!' && sym_name[1] == 'T')
- 	continue;
- 
        sym_name = darwin_strip_name_encoding (sym_name);
  
        sym = alloca (strlen (sym_name) + 2);
--- 900,905 ----
*************** darwin_encode_section_info (tree decl, r
*** 1008,1013 ****
--- 1004,1010 ----
    if ((TREE_CODE (decl) == FUNCTION_DECL
         || TREE_CODE (decl) == VAR_DECL)
        && !DECL_EXTERNAL (decl)
+       && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
        && ((TREE_STATIC (decl)
  	   && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
  	  || (DECL_INITIAL (decl)
*************** update_stubs (const char *name)
*** 1159,1164 ****
--- 1156,1175 ----
  }
  
  void
+ darwin_make_decl_one_only (tree decl)
+ {
+   static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
+   static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
+ 
+   const char *sec = TREE_CODE (decl) == FUNCTION_DECL
+     ? text_section
+     : data_section;
+   TREE_PUBLIC (decl) = 1;
+   DECL_ONE_ONLY (decl) = 1;
+   DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
+ }
+ 
+ void
  machopic_select_section (tree exp, int reloc,
  			 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
  {
*************** darwin_globalize_label (FILE *stream, co
*** 1325,1330 ****
--- 1336,1438 ----
      default_globalize_label (stream, name);
  }
  
+ void
+ darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+ {
+   fprintf (asm_out_file, ".section %s\n", name);
+ }
+ 
+ unsigned int
+ darwin_section_type_flags (tree decl, const char *name, int reloc)
+ {
+   unsigned int flags = default_section_type_flags (decl, name, reloc);
+  
+   /* Weak or linkonce variables live in a writable section.  */
+   if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
+       && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
+     flags |= SECTION_WRITE;
+   
+   return flags;
+ }              
+ 
+ void 
+ darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
+ {
+   /* Darwin does not use unique sections.  However, the target's
+      unique_section hook is called for linkonce symbols.  We need
+      to set an appropriate section for such symbols. */
+   if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
+     darwin_make_decl_one_only (decl);
+ }
+ 
+ /* Emit a label for an FDE, making it global and/or weak if appropriate. 
+    The third parameter is nonzero if this is just a placeholder for an
+    FDE that we are omitting. */
+ void 
+ darwin_output_unwind_label(FILE *file, tree decl, int empty)
+ {
+   tree id = DECL_ASSEMBLER_NAME (decl)
+     ? DECL_ASSEMBLER_NAME (decl)
+     : DECL_NAME (decl);
+ 
+   const char *prefix = "_";
+   const int prefix_len = 1;
+ 
+   const char *base = IDENTIFIER_POINTER (id);
+   unsigned int base_len = IDENTIFIER_LENGTH (id);
+ 
+   const char *suffix = ".eh";
+   unsigned int suffix_len = 3;
+ 
+   int need_quotes = name_needs_quotes (base);
+   int quotes_len = need_quotes ? 2 : 0;
+ 
+   char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
+   lab[0] = '\0';
+ 
+   if (need_quotes)
+     strcat(lab, "\"");
+   strcat(lab, prefix);
+   strcat(lab, base);
+   strcat(lab, suffix);
+   if (need_quotes)
+     strcat(lab, "\"");
+ 
+   if (TREE_PUBLIC (decl))
+     fprintf (file, "%s %s\n",
+ 	     (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
+ 	      ? ".globl"
+ 	      : ".private_extern"),
+ 	     lab);
+ 
+   if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
+     fprintf (file, ".weak_definition %s\n", lab);
+ 
+   if (empty)
+     fprintf (file, "%s = 0\n", lab);
+   else
+     fprintf (file, "%s:\n", lab);
+ 
+   free (lab);
+ }
+ 
+ /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */ 
+ void
+ darwin_non_lazy_pcrel (FILE *file, rtx addr)
+ {
+   const char *str;
+   const char *nlp_name;
+ 
+   if (GET_CODE (addr) != SYMBOL_REF)
+     abort ();
+ 
+   str = darwin_strip_name_encoding (XSTR (addr, 0));
+   nlp_name = machopic_non_lazy_ptr_name (str);
+   fputs ("\t.long\t", file);
+   ASM_OUTPUT_LABELREF (file, nlp_name);
+   fputs ("-.", file);
+ }
+ 
  /* Emit an assembler directive to set visibility for a symbol.  The
     only supported visibilities are VISIBILITY_DEFAULT and
     VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
*************** void
*** 1361,1368 ****
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   const char *p = lab1 + (lab1[0] == '*');
!   int islocaldiff = (p[0] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
--- 1469,1476 ----
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
! 		     && lab2[0] == '*' && lab2[1] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.65
diff -p -r1.65 darwin.h
*** gcc/config/darwin.h	26 Dec 2003 19:13:35 -0000	1.65
--- gcc/config/darwin.h	30 Jan 2004 06:34:33 -0000
*************** do { text_section ();							\
*** 310,315 ****
--- 310,357 ----
  	      "\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", "" , N_SO);	\
     } while (0)
  
+ /* Making a symbols weak on Darwin requires more than just setting DECL_WEAK. */
+ #define MAKE_DECL_ONE_ONLY(DECL) darwin_make_decl_one_only (DECL)
+ 
+ /* Representation of linkonce symbols for the MACH-O assembler. Linkonce
+    symbols must be given a special section *and* must be preceded by a 
+    special assembler directive. */
+ #define ASM_MAKE_LABEL_LINKONCE(FILE,  NAME)                            \
+  do { const char* _x = (NAME); if (!!strncmp (_x, "_OBJC_", 6)) {	\
+   fputs (".weak_definition ", FILE); assemble_name (FILE, _x);		\
+   fputs ("\n", FILE); }} while (0)
+ 
+ /* We support hidden visibility */
+ #undef TARGET_SUPPORTS_HIDDEN
+ #define TARGET_SUPPORTS_HIDDEN 1
+ 
+ /* The Darwin linker imposes two limitations on common symbols: they 
+    can't have hidden visibility, and they can't appear in dylibs.  As
+    a consequence, we should never use common symbols to represent 
+    vague linkage. */
+ #undef USE_COMMON_FOR_ONE_ONLY
+ #define USE_COMMON_FOR_ONE_ONLY 0
+ 
+ /* The Darwin linker doesn't like coalesced symbols to appear in a
+    static archive's table of contents, because it can't handle
+    duplicate entries in a TOC. */
+ #undef TARGET_WEAK_NO_TOC
+ #define TARGET_WEAK_NO_TOC 1
+ 
+ /* We make exception information linkonce. */
+ #undef TARGET_USES_WEAK_UNWIND_INFO
+ #define TARGET_USES_WEAK_UNWIND_INFO 1
+ 
+ /* We need to use a nonlocal label for the start of an EH frame: the
+    Darwin linker requires that a coalesced section start with a label. */
+ #undef FRAME_BEGIN_LABEL
+ #define FRAME_BEGIN_LABEL "EH_frame"
+ 
+ /* Emit a label for the FDE corresponding to DECL.  EMPTY means 
+    emit a label for an empty FDE. */
+ #define ASM_OUTPUT_UNWIND_LABEL(FILE, DECL, EMPTY) \
+   darwin_output_unwind_label ((FILE), (DECL), (EMPTY))
+ 
  /* Our profiling scheme doesn't LP labels and counter words.  */
  
  #define NO_PROFILE_COUNTERS	1
*************** do { text_section ();							\
*** 361,370 ****
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if ((TREE_STATIC (DECL)						\
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!         || DECL_INITIAL (DECL))						\
!       machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
--- 403,413 ----
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))                   \
!       if ((TREE_STATIC (DECL)						\
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!           || DECL_INITIAL (DECL))					\
!         machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
*************** do { text_section ();							\
*** 381,398 ****
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if ((TREE_STATIC (DECL)                                             \
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
!         || DECL_INITIAL (DECL))                                         \
!       machopic_define_name (xname);                                     \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
-     /* Avoid generating stubs for functions we've just defined by	\
-        outputting any required stub name label now.  */			\
-     machopic_output_possible_stub_label (FILE, xname);			\
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
--- 424,439 ----
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))			\
!       if ((TREE_STATIC (DECL)                                           \
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))             \
!           || DECL_INITIAL (DECL))                                       \
!         machopic_define_name (xname);                                   \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
*************** SECTION_FUNCTION (darwin_exception_secti
*** 640,646 ****
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section __TEXT,__eh_frame", 0)	\
  							\
  static void					\
  objc_section_init (void)			\
--- 681,687 ----
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section " EH_FRAME_SECTION_NAME ",__eh_frame" EH_FRAME_SECTION_ATTR, 0)  \
  							\
  static void					\
  objc_section_init (void)			\
*************** objc_section_init (void)			\
*** 681,686 ****
--- 722,731 ----
  #define TARGET_ASM_SELECT_SECTION machopic_select_section
  #undef	TARGET_ASM_SELECT_RTX_SECTION
  #define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
+ #undef  TARGET_ASM_UNIQUE_SECTION
+ #define TARGET_ASM_UNIQUE_SECTION darwin_unique_section
+ 
+ 
  
  #define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME)			\
      do {								\
*************** enum machopic_addr_class {
*** 808,813 ****
--- 853,861 ----
  
  #define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
  
+ #define EH_FRAME_SECTION_NAME   "__TEXT"
+ #define EH_FRAME_SECTION_ATTR ",coalesced,no_toc+strip_static_syms"
+ 
  #undef ASM_PREFERRED_EH_DATA_FORMAT
  #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)  \
    (((CODE) == 2 && (GLOBAL) == 1) \
*************** enum machopic_addr_class {
*** 817,823 ****
--- 865,883 ----
  #define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
    darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
  
+ #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE)	\
+       if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) {				\
+ 	darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR);					\
+ 	goto DONE;									\
+       }
+ 
+ 
  #define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
+ 
+ #undef TARGET_ASM_NAMED_SECTION
+ #define TARGET_ASM_NAMED_SECTION darwin_asm_named_section
+ #undef TARGET_SECTION_TYPE_FLAGS
+ #define TARGET_SECTION_TYPE_FLAGS darwin_section_type_flags
  
  #define DARWIN_REGISTER_TARGET_PRAGMAS()			\
    do {								\
Index: gcc/cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3918
diff -p -r1.3918 ChangeLog
*** gcc/cp/ChangeLog	29 Jan 2004 16:47:10 -0000	1.3918
--- gcc/cp/ChangeLog	30 Jan 2004 06:34:35 -0000
***************
*** 1,3 ****
--- 1,17 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 
+ 	* decl2.c (comdat_linkage): Set visibility of weak symbols to
+ 	VISIBLITY_HIDDEN if user sets the appropriate flag.
+ 	(maybe_make_one_only): Ditto.
+ 	(maybe_emit_vtables): If weak symbols are hidden, be more
+ 	cautious about making vtables weak.
+ 	* method.c (make_thunk): If weak symbols are hidden, be more
+ 	cautious about making thunks weak.
+ 	(use_thunk): Ditto.
+ 	* pt.c (do_type_instantiation): On systems where weak symbols
+ 	don't go in a static archive's TOC, explicit instantiation of a
+ 	class must imply *explicit* instantiation of its memeber.
+ 	
  2004-01-29  Mark Mitchell  <mark@codesourcery.com>
  
  	PR c++/13883
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.697
diff -p -r1.697 decl2.c
*** gcc/cp/decl2.c	26 Jan 2004 17:41:50 -0000	1.697
--- gcc/cp/decl2.c	30 Jan 2004 06:34:37 -0000
*************** void
*** 1359,1365 ****
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     make_decl_one_only (decl);
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
--- 1359,1369 ----
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     {
!       make_decl_one_only (decl);
!       if (flag_hidden_weak)
! 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
!     }
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
*************** maybe_make_one_only (tree decl)
*** 1426,1431 ****
--- 1430,1437 ----
       because their DECL_INITIAL may not have been set properly yet.  */
  
    make_decl_one_only (decl);
+   if (flag_hidden_weak)
+     DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  
    if (TREE_CODE (decl) == VAR_DECL)
      {
*************** maybe_emit_vtables (tree ctype)
*** 1561,1566 ****
--- 1567,1573 ----
    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)
*** 1591,1596 ****
--- 1598,1624 ----
    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: on systems where we don't have weak symbols
+      (obviously), and if weak symbols are given hidden visibility.  In
+      the latter case we make vtables weak only in cases where they
+      really will be emitted in multiple translation units, not in the
+      more common case where we're emitting the vtable in the
+      translation unit containing the definition of a noninline key
+      method. */
+   if (flag_weak && !flag_hidden_weak)
+     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)
*** 1637,1644 ****
  	  DECL_IGNORED_P (vtbl) = 1;
  	}
  
!       /* Always make vtables weak.  */
!       if (flag_weak)
  	comdat_linkage (vtbl);
  
        rest_of_decl_compilation (vtbl, NULL, 1, 1);
--- 1665,1672 ----
  	  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/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.275
diff -p -r1.275 method.c
*** gcc/cp/method.c	2 Jan 2004 15:57:16 -0000	1.275
--- gcc/cp/method.c	30 Jan 2004 06:34:37 -0000
*************** make_thunk (tree function, bool this_adj
*** 153,160 ****
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
    if (flag_weak)
!     comdat_linkage (thunk);
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
--- 153,167 ----
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
+ 
+   /* Always make thunks weak.  Or at least *almost* always.  If weak
+      symbols may be given hidden visibility, we have to be more careful. */
    if (flag_weak)
!     if (!flag_hidden_weak
! 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
! 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
!       comdat_linkage (thunk);
! 
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 390,395 ****
--- 397,407 ----
       rewrite.  */
    TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
    DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
+   if (flag_weak)
+     if (!flag_hidden_weak
+ 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
+ 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
+       comdat_linkage (thunk_fndecl);
  
    if (flag_syntax_only)
      {
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.821
diff -p -r1.821 pt.c
*** gcc/cp/pt.c	26 Jan 2004 17:41:50 -0000	1.821
--- gcc/cp/pt.c	30 Jan 2004 06:34:45 -0000
*************** do_type_instantiation (tree t, tree stor
*** 10576,10581 ****
--- 10576,10582 ----
    int extern_p = 0;
    int nomem_p = 0;
    int static_p = 0;
+   int previous_instantiation_extern_p = 0;
  
    if (TREE_CODE (t) == TYPE_DECL)
      t = TREE_TYPE (t);
*************** do_type_instantiation (tree t, tree stor
*** 10637,10647 ****
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation
! 	 was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
! 	 are we already got marked as an explicit instantiation because of the
! 	 repo file.  All these cases are OK.  */
!       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
--- 10638,10653 ----
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
! 	 instantiation was `extern'.  If EXTERN_P then the second is.
! 	 If -frepo, chances are we already got marked as an explicit
! 	 instantiation because of the repo file.  All these cases are
! 	 OK.  */
! 
!       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
! 
!       if (!previous_instantiation_extern_p && !extern_p
! 	  && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
*************** do_type_instantiation (tree t, tree stor
*** 10658,10663 ****
--- 10664,10670 ----
  
    {
      tree tmp;
+     int explicitly_instantiate_members = 0;
  
      /* In contrast to implicit instantiation, where only the
         declarations, and not the definitions, of members are
*************** do_type_instantiation (tree t, tree stor
*** 10676,10701 ****
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  */
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    mark_decl_instantiated (tmp, extern_p);
! 	    repo_template_instantiated (tmp, extern_p);
! 	    if (! extern_p)
! 	      instantiate_decl (tmp, /*defer_ok=*/1);
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  mark_decl_instantiated (tmp, extern_p);
! 	  repo_template_instantiated (tmp, extern_p);
! 	  if (! extern_p)
! 	    instantiate_decl (tmp, /*defer_ok=*/1);
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
--- 10683,10728 ----
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  Exception:
!        on some targets (e.g. Darwin), weak symbols do not get put in 
!        a static archive's TOC.  The problematic case is if we're doing
!        a non-extern explicit instantiation of an extern template: we
!        have to put member functions in the TOC in that case, or we'll
!        get unresolved symbols at link time. */
! 
!     explicitly_instantiate_members =
!       TARGET_WEAK_NO_TOC
!       && previous_instantiation_extern_p && ! extern_p
!       && ! TYPE_FOR_JAVA (t);
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    if (explicitly_instantiate_members)
! 	      do_decl_instantiation (tmp, NULL_TREE);
! 	    else
! 	      {
! 		mark_decl_instantiated (tmp, extern_p);
! 		repo_template_instantiated (tmp, extern_p);
! 		if (! extern_p)
! 		  instantiate_decl (tmp, /*defer_ok=*/1);
! 	      }
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  if (explicitly_instantiate_members)
! 	    do_decl_instantiation (tmp, NULL_TREE);
! 	  else
! 	    {
! 	      mark_decl_instantiated (tmp, extern_p);
! 	      repo_template_instantiated (tmp, extern_p);
! 	      if (! extern_p)
! 		instantiate_decl (tmp, /*defer_ok=*/1);
! 	    }
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.397
diff -p -r1.397 invoke.texi
*** gcc/doc/invoke.texi	28 Jan 2004 00:14:00 -0000	1.397
--- gcc/doc/invoke.texi	30 Jan 2004 06:34:54 -0000
*************** in the following sections.
*** 182,188 ****
  -fno-nonansi-builtins  -fno-operator-names @gol
  -fno-optional-diags  -fpermissive @gol
  -frepo  -fno-rtti  -fstats  -ftemplate-depth-@var{n} @gol
! -fuse-cxa-atexit  -fno-weak  -nostdinc++ @gol
  -fno-default-inline  -Wabi  -Wctor-dtor-privacy @gol
  -Wnon-virtual-dtor  -Wreorder @gol
  -Weffc++  -Wno-deprecated @gol
--- 182,188 ----
  -fno-nonansi-builtins  -fno-operator-names @gol
  -fno-optional-diags  -fpermissive @gol
  -frepo  -fno-rtti  -fstats  -ftemplate-depth-@var{n} @gol
! -fuse-cxa-atexit  -fno-weak -fhidden-weak -nostdinc++ @gol
  -fno-default-inline  -Wabi  -Wctor-dtor-privacy @gol
  -Wnon-virtual-dtor  -Wreorder @gol
  -Weffc++  -Wno-deprecated @gol
*************** By default, G++ will use weak symbols if
*** 1438,1443 ****
--- 1438,1451 ----
  option exists only for testing, and should not be used by end-users;
  it will result in inferior code and has no benefits.  This option may
  be removed in a future release of G++.
+ 
+ @item -fhidden-weak
+ @opindex fhidden-weak
+ Give hidden visibility to all symbols that the compiler makes weak,
+ such as implicit template instantiations.  This option does not
+ affect the visibility of symbols that the user explicitly declares
+ weak.  If the target does not support both weak symbol support and
+ hidden visibility, this option is ignored.
  
  @item -nostdinc++
  @opindex nostdinc++
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.288
diff -p -r1.288 tm.texi
*** gcc/doc/tm.texi	23 Jan 2004 21:05:21 -0000	1.288
--- gcc/doc/tm.texi	30 Jan 2004 06:35:04 -0000
*************** for the abi and context in the @code{.un
*** 3072,3077 ****
--- 3072,3083 ----
  be updated in @var{fs}.
  @end defmac
  
+ @defmac TARGET_USES_WEAK_UNWIND_INFO
+ A C expression that evaluates to true if the target requires unwind
+ info to be given comdat linkage.  Define it to be @code{1} if comdat
+ linkage is necessary.  The default is @code{0}.
+ @end defmac
+ 
  @node Stack Checking
  @subsection Specifying How Stack Checking is Done
  
*************** setting the @code{DECL_ONE_ONLY} flag is
*** 6730,6741 ****
--- 6736,6771 ----
  be emitted as one-only.
  @end defmac
  
+ @defmac USE_COMMON_FOR_ONE_ONLY
+ A C expression that evaluates to true if the target may use common
+ symbols as one of the mechanisms for representing comdat linkage.
+ The default is @code{1}.  Set this macro to @code{0} if the 
+ target's linking model makes common symbols a poor match for comdat
+ semantics.
+ @end defmac
+ 
  @deftypefn {Target Hook} void TARGET_ASM_ASSEMBLE_VISIBILITY (tree @var{decl}, const char *@var{visibility})
  This target hook is a function to output to @var{asm_out_file} some
  commands that will make the symbol(s) associated with @var{decl} have
  hidden, protected or internal visibility as specified by @var{visibility}.
  @end deftypefn
  
+ @defmac TARGET_WEAK_NO_TOC
+ A C expression that evaluates to true if the target's linker
+ omits symbols with weak linkage from the table of contents of
+ a static archive.  On such systems, some weak symbols must be
+ given special treatment.  The default is @code{0}.
+ @end defmac
+ 
+ @defmac TARGET_SUPPORTS_HIDDEN
+ A C expression that evaluates to true if the target supports hidden
+ visibility.  By default this expression is true if and only if
+ @code{HAS_GAS_HIDDEN} is defined.  Set this macro if the
+ @code{HAS_GAS_HIDDEN} macro gives the wrong answer for this
+ target.  (For example, if the target's mechanism for supporting
+ hidden visibility is not the same as GAS's.)
+ @end defmac
+ 
  @defmac ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
  A C statement (sans semicolon) to output to the stdio stream
  @var{stream} any text necessary for declaring the name of an external
*************** of the preceding label.
*** 7456,7461 ****
--- 7486,7501 ----
  
  If this macro is not defined, nothing special is output at the end of
  the jump-table.
+ @end defmac
+ 
+ @defmac ASM_OUTPUT_UNWIND_LABEL (@var{stream}, @var{decl}, @var{empty})
+ Define this if something special must be output at the beginning of
+ each FDE.  It should write the appropriate label, for the FDE
+ associated with the function declaration @var{decl}, to the stdio
+ stream @var{stream}.  The third argument, @var{empty}, is a boolean:
+ true if this is a placeholder label for an omitted FDE.
+ 
+ If this macro is not defined, FDEs are not given nonlocal labels.
  @end defmac
  
  @node Exception Region Output
Index: gcc/testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.3441
diff -p -r1.3441 ChangeLog
*** gcc/testsuite/ChangeLog	29 Jan 2004 20:56:31 -0000	1.3441
--- gcc/testsuite/ChangeLog	30 Jan 2004 06:35:14 -0000
***************
*** 1,3 ****
--- 1,23 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 	* g++.dg/other/hidden-weak-1.C: New test.
+ 	* g++.dg/other/hidden-weak-2.C: Likewise.
+ 	* g++.dg/other/hidden-weak-3.C: Likewise.
+ 	* g++.dg/other/hidden-weak-4.C: Likewise.
+ 	* g++.dg/other/hidden-weak-5.C: Likewise.
+ 	* g++.dg/other/hidden-weak-6.C: Likewise.
+ 	* g++.dg/other/hidden-weak-7.C: Likewise.
+ 	* g++.dg/other/hidden-weak-8.C: Likewise.
+ 	* g++.dg/other/hidden-weak-9.C: Likewise.
+ 	* g++.dg/other/hidden-weak-10.C: Likewise.
+ 	* g++.dg/other/hidden-weak-11.C: Likewise.
+ 	* g++.dg/other/hidden-weak-12.C: Likewise.
+ 	* g++.dg/other/hidden-weak-13.C: Likewise.
+ 	* g++.dg/other/hidden-weak-14.C: Likewise.
+ 	* g++.dg/other/hidden-weak-15.C: Likewise.
+ 	* g++.dg/other/hidden-weak-16.C: Likewise.
+ 	* g++.dg/other/hidden-weak-17.C: Likewise.
+ 	* g++.dg/other/hidden-weak-18.C: Likewise.
+ 	
  2004-01-29  Geoffrey Keating  <geoffk@geoffk.org>
  
  	* objc.dg/call-super-2.m: Include stddef.h for size_t.
Index: gcc/testsuite/g++.dg/other/hidden-weak-1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-1.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-1.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Implicit instantiation of function template in presence of -fhidden-weak
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-10.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-10.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-10.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-10.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Inline function in presence of -fhidden-weak
+ 
+ inline long fact(long n)
+ {
+   return n <= 0 ? 1 : n * fact(n-1);
+ }
+ 
+ int main()
+ {
+   long result = fact(6);
+   return result == 720 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-11.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-11.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-11.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-11.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z8identityIiET_S0_" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z8identityIiET_S0_" } }
+ 
+ // Implicit instantiation of function template in presence of -fhidden-weak
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-12.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-12.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-12.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-12.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,26 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z5xyzzyIiET_S0_" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z5xyzzyIiET_S0_" } }
+ 
+ // Implicit instantiation of function template with static local variable in 
+ // the presence of -fhidden-weak
+ 
+ template <typename X>
+ X xyzzy (X x)
+ {
+   static bool first = true;
+   static X first_x;
+   if (first)
+     first_x = x;
+   first = false;
+   return first_x;
+ }
+ 
+ int main()
+ {
+   xyzzy(17);
+   return (xyzzy(39) == 17) ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-13.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-13.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-13.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-13.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,41 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ // { dg-final { scan-assembler "\\.weak_definition __ZNK7wrapperIlE3getEv" } }
+ // { dg-final { scan-assembler "\\.private_extern __ZNK7wrapperIlE3getEv" } }
+ 
+ // Implicit instantiation of class template with -fhidden-weak
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   template <typename Y> wrapper(const Y& y);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ template <typename Y>
+ wrapper<X>::wrapper(const Y& y)
+   : val(y)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ int main()
+ {
+   wrapper<long> tmp(17);
+   return tmp.get() == 17l ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-14.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-14.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-14.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-14.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,25 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ // { dg-final { scan-assembler "\\.weak_definition __ZN1AIiE3arrE" } }
+ // { dg-final { scan-assembler "\\.private_extern __ZN1AIiE3arrE" } }
+ 
+ // Implicit instantiation of class template with static array
+ // in the presence of -fhidden-weak
+ 
+ template <typename X>
+ struct A
+ {
+   static X arr[2];
+ };
+ 
+ template <typename X>
+ X A<X>::arr[2] = { 13, 45 };
+ 
+ int main()
+ {
+   bool ok = true;
+   ok = ok && A<int>::arr[0] == 13;
+   ok = ok && A<int>::arr[1] == 45;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-15.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-15.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-15.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-15.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z4factl" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z4factl" } }
+ 
+ // Inline function in presence of -fhidden-weak
+ 
+ inline long fact(long n)
+ {
+   return n <= 0 ? 1 : n * fact(n-1);
+ }
+ 
+ int main()
+ {
+   long result = fact(6);
+   return result == 720 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-2.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-2.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-2.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,24 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Implicit instantiation of function template with static local variable in 
+ // the presence of -fhidden-weak
+ 
+ template <typename X>
+ X xyzzy (X x)
+ {
+   static bool first = true;
+   static X first_x;
+   if (first)
+     first_x = x;
+   first = false;
+   return first_x;
+ }
+ 
+ int main()
+ {
+   xyzzy(17);
+   return (xyzzy(39) == 17) ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-3.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-3.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-3.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,39 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Implicit instantiation of class template with -fhidden-weak
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   template <typename Y> wrapper(const Y& y);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ template <typename Y>
+ wrapper<X>::wrapper(const Y& y)
+   : val(y)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ int main()
+ {
+   wrapper<long> tmp(17);
+   return tmp.get() == 17l ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-4.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-4.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-4.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,40 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Implicit instantiation of class template with static member variable
+ // in the presence of -fhidden-weak
+ 
+ template <typename X>
+ struct wrapper
+ {
+   wrapper();
+   virtual ~wrapper();
+   static X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper()
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ X wrapper<X>::val = 86;
+ 
+ int main()
+ {
+   wrapper<long> tmp;
+   bool ok = true;
+   ok = ok && tmp.val == 86;
+ 
+   tmp.val = 7;
+   wrapper<long> tmp2;
+   ok = ok && tmp2.val == 7;
+   ok = ok && wrapper<char>::val == 86;
+ 
+   return !ok;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-5.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-5.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-5.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,23 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Implicit instantiation of class template with static array
+ // in the presence of -fhidden-weak
+ 
+ template <typename X>
+ struct A
+ {
+   static X arr[2];
+ };
+ 
+ template <typename X>
+ X A<X>::arr[2] = { 13, 45 };
+ 
+ int main()
+ {
+   bool ok = true;
+   ok = ok && A<int>::arr[0] == 13;
+   ok = ok && A<int>::arr[1] == 45;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-6.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-6.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-6.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Explicit instantiation of function template with -fhidden-weak
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ template int identity(int);
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-7.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-7.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-7.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-7.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,40 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Explicit instantiation of class template with -fhidden-weak
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   wrapper(const X& x);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper(const X& x)
+   : val(x)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ template struct wrapper<int>;
+ 
+ int main()
+ {
+   wrapper<int> tmp(17);
+   return tmp.get() == 17 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-8.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-8.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-8.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,33 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Explicit instantiation of class template with static member variable
+ // in the presence of -fhidden-weak
+ 
+ template <typename X>
+ struct wrapper
+ {
+   wrapper();
+   virtual ~wrapper();
+   static X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper()
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ X wrapper<X>::val = 86;
+ 
+ template struct wrapper<int>;
+ 
+ int main()
+ {
+   return wrapper<int>::val == 86 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-9.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-9.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-9.C	30 Jan 2004 06:35:16 -0000
***************
*** 0 ****
--- 1,22 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-weak" }
+ 
+ // Polymorphic class with no key method in the presence of -fhidden-weak
+ 
+ struct X
+ {
+ public:
+   X(int n) : val(n) { }
+   virtual ~X() { }
+   virtual int get() const { return val; }
+ private:
+   int val;
+ };
+ 
+ int main()
+ {
+   X* pX = new X(13);
+   return pX->get() == 13 ? 0 : 1;
+ }
Index: libffi/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libffi/ChangeLog,v
retrieving revision 1.157
diff -p -r1.157 ChangeLog
*** libffi/ChangeLog	25 Jan 2004 06:58:33 -0000	1.157
--- libffi/ChangeLog	30 Jan 2004 06:35:22 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2004-01-29  Matt Austern  <austern@apple.com>
+ 	* src/powerpc/darwin.S: Change EH information in assembly glue to
+ 	match EH format changes in the compiler.
+ 	* src/powerpc/darwin_closure.S: Ditto.
+ 	
  2004-01-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
  
  	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
Index: libffi/src/powerpc/darwin.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin.S,v
retrieving revision 1.7
diff -p -r1.7 darwin.S
*** libffi/src/powerpc/darwin.S	21 Oct 2003 19:01:56 -0000	1.7
--- libffi/src/powerpc/darwin.S	30 Jan 2004 06:35:22 -0000
*************** _ffi_call_AIX:
*** 162,169 ****
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 162,169 ----
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 173,191 ****
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte   0x1     ; uleb128 0x1; Augmentation size
! 	.byte   0x10    ; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
--- 173,192 ----
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_call_DARWIN.eh
+ _ffi_call_DARWIN.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.long	LASFDE1-EH_frame1 ; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
Index: libffi/src/powerpc/darwin_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin_closure.S,v
retrieving revision 1.6
diff -p -r1.6 darwin_closure.S
*** libffi/src/powerpc/darwin_closure.S	18 Sep 2003 19:35:46 -0000	1.6
--- libffi/src/powerpc/darwin_closure.S	30 Jan 2004 06:35:22 -0000
*************** Lfinish:
*** 234,241 ****
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 234,241 ----
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 246,264 ****
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x10	; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range
--- 246,265 ----
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_closure_ASM.eh
+ _ffi_closure_ASM.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.long	LASFDE1-EH_frame1	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range

[-- Attachment #3: Type: text/plain, Size: 1 bytes --]



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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-30 16:53 ` [Darwin] Patch, take 2: " Matt Austern
@ 2004-01-31  0:05   ` Richard Henderson
  2004-01-31  1:20     ` Matt Austern
  0 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2004-01-31  0:05 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc, gcc-patches

On Fri, Jan 30, 2004 at 08:34:57AM -0800, Matt Austern wrote:
> The solution we came up with, which Apple has been using in our locally 
> modified compiler for two years, is to coalesce FDEs too.  We give 
> every FDE its own symbol (the name we choose is <foo>.eh, where <foo> 
> is the assembler name of the function the FDE corresponds to), so that 
> the FDEs too are coalesced.

Seems reasonable.

> To support all this exception machinery I put in a link from 
> dw_fde_struct back to the associated decl (we'll need that for other 
> targets, anyway, when and if we move to ELF group COMDAT), and I 
> introduced a new target macro, ASM_OUTPUT_UNWIND_LABEL, to give FDEs 
> their labels.  Everywhere but Darwin, that macro does nothing.

I'd definitely want this in the target structure, since it's 
quite clearly not a performance problem.

> I introduced a new target macro,  TARGET_WEAK_NO_TOC, 
> to control this behavior.

You'll have to get Jason to comment on this.  I certainly don't 
understand C++ linkage to know.

The name of the macro is pretty Darwin biased though.  When I 
look at it I think powerpc toc, as that's the only thing that
comes close to matching.

> Second quirk: Common is bad news.  Common symbols in Darwin can't have 
> hidden visibility and can't be exported from dylibs.   The second is 
> deliberate and the first is a bug, but both of them are things we have 
> to deal with.  So we really just shouldn't ever use common to implement 
> vague linkage, we should always use coalescing instead.  I introduced 
> another target macro, USE_COMMON_FOR_ONE_ONLY, so we can tell the 
> compiler about targets where common is a poor choice for representing 
> vague linkage.  (Again: this is not the same thing as -fno-common.  
> Common is fine in its place, just not for vague linkage.)

When do we do COMMON for C++?  Neither ELF-style nor GNU-style linkonce
should be using common symbols either.  Unless I'm missing something, I
wouldn't think we'd use COMMON with SUPPORTS_ONE_ONLY targets.

> Finally, one new user-visible feature: -fhidden-weak.  This flag makes 
> the compiler automatically give hidden visibility to symbols that have 
> vague linkage.

That does sound like it might prevent accidents, yes.

> Potentially questionable decisions.  First, I'm keying this off 
> DECL_ONE_ONLY, not DECL_WEAK.

That does sound better for your goal, but I'd rename the switch
lest it be confusing, -fhidden-linkonce or something.


r~

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-31  0:05   ` Richard Henderson
@ 2004-01-31  1:20     ` Matt Austern
  2004-02-02 18:47       ` Jason Merrill
  0 siblings, 1 reply; 17+ messages in thread
From: Matt Austern @ 2004-01-31  1:20 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc, gcc-patches

On Jan 30, 2004, at 4:01 PM, Richard Henderson wrote:

>> To support all this exception machinery I put in a link from
>> dw_fde_struct back to the associated decl (we'll need that for other
>> targets, anyway, when and if we move to ELF group COMDAT), and I
>> introduced a new target macro, ASM_OUTPUT_UNWIND_LABEL, to give FDEs
>> their labels.  Everywhere but Darwin, that macro does nothing.
>
> I'd definitely want this in the target structure, since it's
> quite clearly not a performance problem.

OK, I'm happy to make that change.

>
>> I introduced a new target macro,  TARGET_WEAK_NO_TOC,
>> to control this behavior.
>
> You'll have to get Jason to comment on this.  I certainly don't
> understand C++ linkage to know.
>
> The name of the macro is pretty Darwin biased though.  When I
> look at it I think powerpc toc, as that's the only thing that
> comes close to matching.

Do you have a better suggestion for the name?  The problem is that
it really is a pretty esoteric issue: the issue is that if something is 
an
implicit instantiation that only happens once, and where we don't
expect other implicit instantiations to happen in other translation 
units,
and when there's a chance that the translation unit we're compiling
might find its way into a static archive, then on Darwin we need to make
it into an explicit instantiation instead of an implicit one.  I called 
it
TARGET_WEAK_NO_TOC because the issue is that, on Darwin,
coalesced symbols don't make it into the static archive's table of
contents.

Maybe it would be more honest if I didn't try to make up a target macro
for this, since it's just a very specific quirk, but just explicitly 
special-
case Darwin.  That's an ugly solution, but then, it's an ugly problem.

(For that matter, I wouldn't even mind too much just leaving this part
of the patch out, and dealing with the problem later.  It's required for
correctness, but only in pretty esoteric cases.  All of the tests in the
test suite work just as well without this.)

> When do we do COMMON for C++?  Neither ELF-style nor GNU-style linkonce
> should be using common symbols either.  Unless I'm missing something, I
> wouldn't think we'd use COMMON with SUPPORTS_ONE_ONLY targets.

The relevant code is in make_decl_one_only, which is in varasm.c.  (It's
used by the C++ front end and also in one place in dwarf2out.c; I 
suspect
it's indirectly used by the C++ front end there, too.)

Here's the case where we use COMMON even on SUPPORTS_ONE_ONLY
targets:
  if (TREE_CODE (decl) == VAR_DECL
       && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == 
error_mark_node))
     DECL_COMMON (decl) = 1;
   else if (SUPPORTS_ONE_ONLY)
     ...

I agree, it looks funny.  Unless someone can explain to me why this is 
a good
idea, I'd be happy to exchange the order of those clauses so that we 
never
use COMMON if we've got ONE_ONLY available.  The only reason I didn't
propose that in my original patch is that I wanted to be conservative, 
and not
change the behavior of any non-Darwin targets.

>> Finally, one new user-visible feature: -fhidden-weak.  This flag makes
>> the compiler automatically give hidden visibility to symbols that have
>> vague linkage.
>
> That does sound like it might prevent accidents, yes.
>
>> Potentially questionable decisions.  First, I'm keying this off
>> DECL_ONE_ONLY, not DECL_WEAK.
>
> That does sound better for your goal, but I'd rename the switch
> lest it be confusing, -fhidden-linkonce or something.

I have no problem with that.

			--Matt

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-31  1:20     ` Matt Austern
@ 2004-02-02 18:47       ` Jason Merrill
  2004-02-02 19:00         ` Matt Austern
  0 siblings, 1 reply; 17+ messages in thread
From: Jason Merrill @ 2004-02-02 18:47 UTC (permalink / raw)
  To: Matt Austern; +Cc: Richard Henderson, gcc, gcc-patches

On Fri, 30 Jan 2004 17:06:17 -0800, Matt Austern <austern@apple.com> wrote:

> Here's the case where we use COMMON even on SUPPORTS_ONE_ONLY
> targets:
>   if (TREE_CODE (decl) == VAR_DECL
>        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) ==
> error_mark_node))
>      DECL_COMMON (decl) = 1;
>    else if (SUPPORTS_ONE_ONLY)
>      ...
>
> I agree, it looks funny.  Unless someone can explain to me why this is a
> good idea, I'd be happy to exchange the order of those clauses so that we
> never use COMMON if we've got ONE_ONLY available.

I was doing it that way out of a philosophy of using a more advanced
feature only when necessary.  COMMON objects are merged by any Unix linker,
and they take up no space in the object file.  But if using COMMON is
problematic, I'm certainly not attached to it.

>>> Finally, one new user-visible feature: -fhidden-weak.  This flag makes
>>> the compiler automatically give hidden visibility to symbols that have
>>> vague linkage.

Sounds like this would block sharing of template instantiations and RTTI
information between an executable and a shared library, which would break a
lot of code.

Jason

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 18:47       ` Jason Merrill
@ 2004-02-02 19:00         ` Matt Austern
  2004-02-02 19:12           ` Jason Merrill
  2004-02-02 22:39           ` [Darwin] Patch, take 2: enable linkonce support for Darwin Mike Stump
  0 siblings, 2 replies; 17+ messages in thread
From: Matt Austern @ 2004-02-02 19:00 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc, gcc-patches, Richard Henderson

On Feb 2, 2004, at 10:47 AM, Jason Merrill wrote:

> On Fri, 30 Jan 2004 17:06:17 -0800, Matt Austern <austern@apple.com> 
> wrote:
>
>> Here's the case where we use COMMON even on SUPPORTS_ONE_ONLY
>> targets:
>>   if (TREE_CODE (decl) == VAR_DECL
>>        && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) ==
>> error_mark_node))
>>      DECL_COMMON (decl) = 1;
>>    else if (SUPPORTS_ONE_ONLY)
>>      ...
>>
>> I agree, it looks funny.  Unless someone can explain to me why this 
>> is a
>> good idea, I'd be happy to exchange the order of those clauses so 
>> that we
>> never use COMMON if we've got ONE_ONLY available.
>
> I was doing it that way out of a philosophy of using a more advanced
> feature only when necessary.  COMMON objects are merged by any Unix 
> linker,
> and they take up no space in the object file.  But if using COMMON is
> problematic, I'm certainly not attached to it.

OK!  As you may have noticed, version 3 of my patch avoids COMMON
on all platforms where ONE_ONLY is available.  This is the only part of
my patch that changes the compiler's behavior for any target other than
Darwin.

>
>>>> Finally, one new user-visible feature: -fhidden-weak.  This flag 
>>>> makes
>>>> the compiler automatically give hidden visibility to symbols that 
>>>> have
>>>> vague linkage.
>
> Sounds like this would block sharing of template instantiations and 
> RTTI
> information between an executable and a shared library, which would 
> break a
> lot of code.

Not necessarily as much code as you might think!  Most Unix linkers have
the property that implicit instantiations are shared between different 
shared
libraries, but that's not the way it works on MS-Windows.  Anyone who's
writing code that's portable between Unix and Windows isn't relying on 
that
sort of sharing.

But yes, you're  basically right: this is a fairly big change in 
semantics.
That's why it's not the default, even on Darwin.

			--Matt


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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 19:00         ` Matt Austern
@ 2004-02-02 19:12           ` Jason Merrill
  2004-02-02 23:30             ` Matt Austern
  2004-02-03 22:11             ` -fhidden-one-only and the EH runtime Matt Austern
  2004-02-02 22:39           ` [Darwin] Patch, take 2: enable linkonce support for Darwin Mike Stump
  1 sibling, 2 replies; 17+ messages in thread
From: Jason Merrill @ 2004-02-02 19:12 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc, gcc-patches, Richard Henderson

On Mon, 2 Feb 2004 11:00:26 -0800, Matt Austern <austern@apple.com> wrote:

> On Feb 2, 2004, at 10:47 AM, Jason Merrill wrote:
>
>> On Fri, 30 Jan 2004 17:06:17 -0800, Matt Austern <austern@apple.com>
>> wrote:
>>
>>>>> Finally, one new user-visible feature: -fhidden-weak.  This flag makes
>>>>> the compiler automatically give hidden visibility to symbols that have
>>>>> vague linkage.
>>
>> Sounds like this would block sharing of template instantiations and RTTI
>> information between an executable and a shared library, which would
>> break a lot of code.
>
> Not necessarily as much code as you might think!  Most Unix linkers have
> the property that implicit instantiations are shared between different
> shared libraries, but that's not the way it works on MS-Windows.  Anyone
> who's writing code that's portable between Unix and Windows isn't relying
> on that sort of sharing.

The code may not be, but the compiler is for internal data structures like
RTTI info.  Does throwing an exception between shared objects work with
-fhidden-weak?

Jason

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 19:00         ` Matt Austern
  2004-02-02 19:12           ` Jason Merrill
@ 2004-02-02 22:39           ` Mike Stump
  2004-02-02 22:55             ` Matt Austern
  1 sibling, 1 reply; 17+ messages in thread
From: Mike Stump @ 2004-02-02 22:39 UTC (permalink / raw)
  To: Matt Austern; +Cc: Jason Merrill, gcc, gcc-patches, Richard Henderson

On Monday, February 2, 2004, at 11:00 AM, Matt Austern wrote:
> OK!  As you may have noticed, version 3 of my patch avoids COMMON
> on all platforms where ONE_ONLY is available.

I can't help but wonder if this results in larger .o files (ls -l type 
sizes), or slower compiles...  and how big of an effect it is.

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 22:39           ` [Darwin] Patch, take 2: enable linkonce support for Darwin Mike Stump
@ 2004-02-02 22:55             ` Matt Austern
  2004-02-02 23:26               ` Mike Stump
  2004-02-02 23:40               ` Jason Merrill
  0 siblings, 2 replies; 17+ messages in thread
From: Matt Austern @ 2004-02-02 22:55 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc, gcc-patches, Richard Henderson, Jason Merrill

On Feb 2, 2004, at 2:39 PM, Mike Stump wrote:

> On Monday, February 2, 2004, at 11:00 AM, Matt Austern wrote:
>> OK!  As you may have noticed, version 3 of my patch avoids COMMON
>> on all platforms where ONE_ONLY is available.
>
> I can't help but wonder if this results in larger .o files (ls -l type 
> sizes), or slower compiles...  and how big of an effect it is.

Slower compile, I can't think of any reason to wonder that.  Larger .o 
files...  Conceivably it could increase or decrease the size of the .o 
files, but the effect is almost certainly negligible.  The compiler 
currently uses COMMON for C++ vague linkage only in a few pretty rare 
cases.  Changing it from "used in a few corner cases" to "not used" 
isn't a big deal, pretty much by definition.

And, of course, we don't have a choice for Darwin.  The only question 
is whether to make this change for Darwin only or to make it uniformly. 
  Unless there's a compelling reason, I prefer the latter.

			--Matt

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 22:55             ` Matt Austern
@ 2004-02-02 23:26               ` Mike Stump
  2004-02-02 23:40               ` Jason Merrill
  1 sibling, 0 replies; 17+ messages in thread
From: Mike Stump @ 2004-02-02 23:26 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc, gcc-patches, Richard Henderson, Jason Merrill

On Monday, February 2, 2004, at 02:55 PM, Matt Austern wrote:
>>> OK!  As you may have noticed, version 3 of my patch avoids COMMON
>>> on all platforms where ONE_ONLY is available.
>>
>> I can't help but wonder if this results in larger .o files (ls -l 
>> type sizes), or slower compiles...  and how big of an effect it is.
>
> Slower compile, I can't think of any reason to wonder that.  Larger .o 
> files...  Conceivably it could increase or decrease the size of the .o 
> files, but the effect is almost certainly negligible.  The compiler 
> currently uses COMMON for C++ vague linkage only in a few pretty rare 
> cases.

Ah, sorry, I was thinking of the change that did this by default for 
all languages (including C), as C has the same problem that C++ does on 
darwin about dylibs and common, not your change.

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 19:12           ` Jason Merrill
@ 2004-02-02 23:30             ` Matt Austern
  2004-02-03 22:11             ` -fhidden-one-only and the EH runtime Matt Austern
  1 sibling, 0 replies; 17+ messages in thread
From: Matt Austern @ 2004-02-02 23:30 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc, gcc-patches, Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 1823 bytes --]

On Feb 2, 2004, at 11:11 AM, Jason Merrill wrote:

> On Mon, 2 Feb 2004 11:00:26 -0800, Matt Austern <austern@apple.com> 
> wrote:
>
>> On Feb 2, 2004, at 10:47 AM, Jason Merrill wrote:
>>
>>> On Fri, 30 Jan 2004 17:06:17 -0800, Matt Austern <austern@apple.com>
>>> wrote:
>>>
>>>>>> Finally, one new user-visible feature: -fhidden-weak.  This flag 
>>>>>> makes
>>>>>> the compiler automatically give hidden visibility to symbols that 
>>>>>> have
>>>>>> vague linkage.
>>>
>>> Sounds like this would block sharing of template instantiations and 
>>> RTTI
>>> information between an executable and a shared library, which would
>>> break a lot of code.
>>
>> Not necessarily as much code as you might think!  Most Unix linkers 
>> have
>> the property that implicit instantiations are shared between different
>> shared libraries, but that's not the way it works on MS-Windows.  
>> Anyone
>> who's writing code that's portable between Unix and Windows isn't 
>> relying
>> on that sort of sharing.
>
> The code may not be, but the compiler is for internal data structures 
> like
> RTTI info.  Does throwing an exception between shared objects work with
> -fhidden-weak?

Good point.  This does work in Apple's locally modified compiler, but
only because of some other changes that we made.  I'll have to port
those extra changes over too.  There's a fourth version of my patch
in the works...  (Yes, it really is better for me to go through the 
effort
of making -fhidden-one-only work than to remove that feature.  Darwin
has enough complicated linker features that something like this is
sometimes an important simplification.)

Also looks like I'd *really* better figure out how to get complicated 
multi-
file test cases into the dg framework.  Here's the sort of test case 
that I
need to check this sort of thing:

[-- Attachment #2: eh-hidden-one-only.tar --]
[-- Type: application/x-tar, Size: 10240 bytes --]

[-- Attachment #3: Type: text/plain, Size: 125 bytes --]



I don't know how to make something like this a dg test case.  If anyone
has advice on that, I'd appreciate it.

			--Matt


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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-02-02 22:55             ` Matt Austern
  2004-02-02 23:26               ` Mike Stump
@ 2004-02-02 23:40               ` Jason Merrill
  1 sibling, 0 replies; 17+ messages in thread
From: Jason Merrill @ 2004-02-02 23:40 UTC (permalink / raw)
  To: Matt Austern; +Cc: Mike Stump, gcc, gcc-patches, Richard Henderson

On Mon, 2 Feb 2004 14:55:52 -0800, Matt Austern <austern@apple.com> wrote:

> On Feb 2, 2004, at 2:39 PM, Mike Stump wrote:
>
>> On Monday, February 2, 2004, at 11:00 AM, Matt Austern wrote:
>>> OK!  As you may have noticed, version 3 of my patch avoids COMMON
>>> on all platforms where ONE_ONLY is available.
>>
>> I can't help but wonder if this results in larger .o files (ls -l type
>> sizes), or slower compiles...  and how big of an effect it is.
>
> Slower compile, I can't think of any reason to wonder that.  Larger .o
> files...  Conceivably it could increase or decrease the size of the .o
> files, but the effect is almost certainly negligible.  The compiler
> currently uses COMMON for C++ vague linkage only in a few pretty rare
> cases.  Changing it from "used in a few corner cases" to "not used" isn't a
> big deal, pretty much by definition.

And it should just change from .common to .bss, which doesn't take up any
more space in .o files.

Jason

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

* -fhidden-one-only and the EH runtime
  2004-02-02 19:12           ` Jason Merrill
  2004-02-02 23:30             ` Matt Austern
@ 2004-02-03 22:11             ` Matt Austern
  1 sibling, 0 replies; 17+ messages in thread
From: Matt Austern @ 2004-02-03 22:11 UTC (permalink / raw)
  To: libstdc++, gcc mailing list; +Cc: Richard Henderson, Jason Merrill

Aha!  Took me long enough, but I finally figured out why throwing an 
exception from one dylib and catching it in another actually worked in 
Apple's modified compiler, even though we'd made our typenames 
coalesced and private extern.  (In non-Apple terminology: weak and 
hidden.)

The answer: basically it was by accident.  Tracing through:
   1. The EH runtime compares two typeinfo objects with operator==.
   2. When operator== looks at two typeinfo objects, it first checks to 
see if they have the same address.  If they do, they're equal.  If they 
don't have the same address, and if __GXX_MERGED_TYPEINFO_NAMES is 
true, then they aren't equal.  If they don't have the same address and 
__GXX_MERGED_TYPEINFO_NAMES is not true, then it does string comparison 
on the names.
   3. This macro is set when libstdc++ is built.   It gets the same 
value as __GXX_WEAK__, which is set by the compiler.
   4. Finally, the compiler defines __GXX_WEAK__ to true iff it is built 
with SUPPORTS_ONE_ONLY.

So that's the accident: in Apple's compiler we've got the moral 
equivalent of ONE_ONLY semantics, but we didn't define 
SUPPORTS_ONE_ONLY.  That meant we didn't get 
__GXX_MERGED_TYPEINFO_NAMES, which meant the EH runtime allowed us to 
fall back on string comparison for typeinfo equality testing.

OK, now that I understand what's going on, let's get back to the 
original question: what do we have to do to support a compilation mode 
in which linkonce symbols are given hidden visibility?  The answer is 
that this is messier than I would have liked: you have to decide, when 
compiling libstdc++, whether or not you want to support such a mode.  
So the options I see are:
  1. Unconditionally enable that mode.  That is, define typeinfo's 
operator== so that it always falls back on string comparison when 
pointer comparison fails.
  2. Conditionally enable that mode.  (Perhaps controlled by a new 
configure switch?) If that mode isn't enabled, then the compiler will 
issue an error message for -fhidden-one-only.
  3. Forget about this mode, and remove it from my patch.  One-only 
symbols have global visibility, and that's that.

I've listed these options in order of my preference.  I can't actually 
think of a reason not to have typeinfo's operator== fall back on string 
comparison.  Sure it'll make it slower to see that a typeinfo 
comparison fails, but I don't think typeinfo comparison is ever used in 
a place where performance matters.  If anyone can show me a place where 
the performance of typeinfo's operator== is important, or where falling 
back on string comparison would cause a subtle correctness problem I 
didn't notice, then I'll change my mind.

			--Matt

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

* [Darwin] Patch, take 2: enable linkonce support for Darwin
@ 2004-02-01  5:53 Matt Austern
  0 siblings, 0 replies; 17+ messages in thread
From: Matt Austern @ 2004-02-01  5:53 UTC (permalink / raw)
  To: gcc, gcc-patches; +Cc: Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 927 bytes --]

This is very similar to my previous patch.  I've tried to address 
Richard's stylistic comments (target hook versus target macro, for 
example).

I also found one place where my previous patch wasn't quite right: on 
Darwin we need to make sure that explicit template instantiations are 
not marked coalesced.  This is tied up in the whole 
static-archive-table-of-contents mess.  I've fixed the bug (see 
maybe_make_one_only), and I have a test for this whole corner case.  
That test is not part of this patch, because it involves multiple 
compile and link steps and the creation of a static archive; I don't 
know how to put such a complicated test into dg.  When and if I learn 
how to do that, I'll submit it as a separate patch.

Still bootstrapped on OS X, still fixes a bunch of test cases in g++.dg 
and doesn't cause any regressions in the C, C++, or libstdc++ test 
suites.

OK to commit to  mainline?


			--Matt


[-- Attachment #2: weak-darwin-3.txt --]
[-- Type: text/plain, Size: 71067 bytes --]

Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.2592
diff -p -r2.2592 ChangeLog
*** gcc/ChangeLog	31 Jan 2004 23:21:20 -0000	2.2592
--- gcc/ChangeLog	1 Feb 2004 05:51:22 -0000
***************
*** 1,3 ****
--- 1,63 ----
+ 2004-01-31  Matt Austern  <austern@apple.com>
+ 
+ 	* c-opts.c (c_common_handle_option): Add -fhidden-one-only option.
+ 	* c.opt: Likewise.
+ 	* flags.h (flag_hidden_one_only): flag for -fhidden-one-only option.
+ 	* toplev.c (flag_hidden_one_only): Likewise.
+ 	* target.h (struct gcc_target): New target hook, unwind_label.
+ 	* target-def.h (TARGET_ASM_EMIT_UNWIND_LABEL): New hook.
+ 	* output.h (default_emit_unwind_label): New function.
+ 	* default.h (TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): New macro.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): New target macro.
+ 	(TARGET_SUPPORTS_HIDDEN): New target macro.
+ 	* dwarf2out.c (struct dw_fde_struct): Add field for function decl
+ 	that corresponds to this FDE.
+ 	(FRAME_BEGIN_LABEL): Allow target to override default label.
+ 	(output_call_frame_info): If FDEs are linknonce, then use extra
+ 	indirection for FDE encoding, output a label for each FDE, and 
+ 	output an empty label for each function without an FDE.
+ 	(dwarf2out_begin_prologue): Set up decl field when creating an FDE.
+ 	* varasm.c (globalize_decl): Call ASM_MAKE_LABEL_LINKONCE for
+ 	decls with DECL_ONE_ONLY set, if that macro is defined.
+ 	(make_decl_one_only): Don't use DECL_COMMON if we're compiling
+ 	for a SUPPORTS_ONE_ONLY target.
+ 	* config/darwin-protos.h (darwin_unique_section): Declare.
+ 	(darwin_asm_named_section): Likewise.
+ 	(darwin_section_type_flags): Likewise.
+ 	(darwin_non_lazy_pcrel): Likewise.
+ 	(darwin_emit_unwind_label): Likewise.
+ 	(darwin_make_decl_one_only): Likewise.
+ 	* config/darwin.c (machopic_finish): Get rid of tweak that
+ 	eliminate stubs for symbols that are defined.
+ 	(darwin_encode_section_info): Don't treat weak functiosn as defined.
+ 	(darwin_make_decl_one_only): Define.
+ 	(darwin_asm_named_section): Likewise.
+ 	(darwin_section_type_flags): Likewise.
+ 	(darwin_unique_section): Likewise.
+ 	(darwin_emit_unwind_label): Likewise.
+ 	(darwin_non_lazy_pcrel): Likewise.
+ 	(darwin_asm_output_dwarf_delta): Difference between two labels is
+ 	local only if both labels are local.
+ 	* config/darwin.h (MAKE_DECL_ONE_ONLY): Define.
+ 	(ASM_MAKE_LABEL_LINKONCE): Likewise.
+ 	(TARGET_SUPPORTS_HIDDEN): Likewise.
+ 	(TARGET_USES_WEAK_UNWIND_INFO): Likewise.
+ 	(TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY): Likewise.
+ 	(FRAME_BEGIN_LABEL): Likewise.
+ 	(ASM_DECLARE_OBJECT_NAME): Make references to weak symbols indirect.
+ 	(ASM_DECLARE_FUNCTION_NAME): Likewise.
+ 	(darwin_eh_frame_section): Give __eh_frame section the coalesced flag.
+ 	(TARGET_ASM_UNIQUE_SECTION): Define.
+ 	(EH_FRAME_SECTION_NAME): Define.
+ 	(EH_FRAME_SECTION_ATTR): Likewise.
+ 	(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): Likewise.
+ 	(TARGET_ASM_NAMED_SECTION): Likewise.
+ 	(TARGET_SECTION_TYPE_FLAGS): Likewise.
+ 	* config/invoke.texi: Deocument -fhidden-one-only.
+ 	* config/tm.texi: Document TARGET_USES_WEAK_UNWIND_INFO,
+ 	TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY, TARGET_SUPPORTS_HIDDEN,
+ 	TARGET_ASM_EMIT_UNWIND_LABEL.
+ 	
  2004-01-31  Kazu Hirata  <kazu@cs.umass.edu>
  
  	* config/c4x/c4x.md: Use GEN_INT instead of
Index: gcc/c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.98
diff -p -r1.98 c-opts.c
*** gcc/c-opts.c	21 Jan 2004 20:39:51 -0000	1.98
--- gcc/c-opts.c	1 Feb 2004 05:51:24 -0000
*************** c_common_handle_option (size_t scode, co
*** 916,921 ****
--- 916,932 ----
        flag_weak = value;
        break;
  
+     case OPT_fhidden_one_only:
+       flag_hidden_one_only = value;
+ #if !TARGET_SUPPORTS_HIDDEN
+       if (value)
+ 	{
+ 	  warning ("-fhidden-one-only not supported for this target, ignored");
+ 	  flag_hidden_one_only = 0;
+ 	}
+ #endif
+       break;
+ 
      case OPT_fzero_link:
        flag_zero_link = value;
        break;
Index: gcc/c.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c.opt,v
retrieving revision 1.17
diff -p -r1.17 c.opt
*** gcc/c.opt	25 Sep 2003 01:25:50 -0000	1.17
--- gcc/c.opt	1 Feb 2004 05:51:24 -0000
*************** fweak
*** 666,671 ****
--- 666,675 ----
  C++ ObjC++
  Emit common-like symbols as weak symbols
  
+ fhidden-one-only
+ C++ ObjC++
+ Give common-like symbols hidden visibility on targets that support it
+ 
  fwide-exec-charset=
  C ObjC C++ ObjC++ Joined RejectNegative
  -fwide-exec-charset=<cset>	Convert all wide strings and character constants to character set <cset>
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.126
diff -p -r1.126 defaults.h
*** gcc/defaults.h	21 Jan 2004 20:39:53 -0000	1.126
--- gcc/defaults.h	1 Feb 2004 05:51:24 -0000
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 237,242 ****
--- 237,253 ----
  #endif
  #endif
  
+ /* Determines whether explicit template instantiations should
+    be given link-once semantics. */
+ #ifndef TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
+ # define TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY 1
+ #endif
+ 
+ /* This determines whether or not we need linkonce unwind information */
+ #ifndef TARGET_USES_WEAK_UNWIND_INFO
+ #define TARGET_USES_WEAK_UNWIND_INFO 0
+ #endif
+ 
  /* By default, there is no prefix on user-defined symbols.  */
  #ifndef USER_LABEL_PREFIX
  #define USER_LABEL_PREFIX ""
*************** do { fputs (integer_asm_op (POINTER_SIZE
*** 257,262 ****
--- 268,291 ----
  #  define TARGET_ATTRIBUTE_WEAK
  # endif
  #endif
+ 
+ /* This determines whether this target supports hidden visibility.
+    This is a weaker condition than HAVE_GAS_HIDDEN, which probes for
+    specific assembler syntax. */
+ #ifndef TARGET_SUPPORTS_HIDDEN
+ # ifdef HAVE_GAS_HIDDEN
+ #  define TARGET_SUPPORTS_HIDDEN 1
+ # else
+ #  define TARGET_SUPPORTS_HIDDEN 0
+ # endif
+ #endif
+ 
+ /* Determines whether we may use common symbols to represent one-only
+    semantics (a.k.a. "vague linkage"). */
+ #ifndef USE_COMMON_FOR_ONE_ONLY
+ # define USE_COMMON_FOR_ONE_ONLY 1
+ #endif
+ 
  
  /* If the target supports init_priority C++ attribute, give
     SUPPORTS_INIT_PRIORITY a nonzero value.  */
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.483
diff -p -r1.483 dwarf2out.c
*** gcc/dwarf2out.c	29 Jan 2004 18:42:56 -0000	1.483
--- gcc/dwarf2out.c	1 Feb 2004 05:51:37 -0000
*************** typedef struct cfa_loc GTY(())
*** 243,248 ****
--- 243,249 ----
  
  typedef struct dw_fde_struct GTY(())
  {
+   tree decl;
    const char *dw_fde_begin;
    const char *dw_fde_current_label;
    const char *dw_fde_end;
*************** static void def_cfa_1 (const char *, dw_
*** 391,397 ****
--- 392,400 ----
  #define FUNC_END_LABEL		"LFE"
  #endif
  
+ #ifndef FRAME_BEGIN_LABEL
  #define FRAME_BEGIN_LABEL	"Lframe"
+ #endif
  #define CIE_AFTER_SIZE_LABEL	"LSCIE"
  #define CIE_END_LABEL		"LECIE"
  #define FDE_LABEL		"LSFDE"
*************** output_call_frame_info (int for_eh)
*** 1942,1947 ****
--- 1945,1966 ----
    if (fde_table_in_use == 0)
      return;
  
+   /* If we make FDEs linkonce, we may have to emit an empty label for
+      an FDE that wouldn't otherwise be emitted.  We want to avoid
+      having an FDE kept around when the function it refers to is
+      discarded. (Example where this matters: a primary function
+      template in C++ requires EH information, but an explicit
+      specialization doesn't. */
+   if (TARGET_USES_WEAK_UNWIND_INFO
+       && ! flag_asynchronous_unwind_tables
+       && for_eh)
+     for (i = 0; i < fde_table_in_use; i++)
+       if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls)
+           && !fde_table[i].uses_eh_lsda
+ 	  && ! DECL_ONE_ONLY (fde_table[i].decl))
+ 	(*targetm.asm_out.unwind_label) (asm_out_file, fde_table[i].decl,
+ 					 /* empty */ 1);
+ 
    /* If we don't have any functions we'll want to unwind out of, don't
       emit any EH unwind information.  Note that if exceptions aren't
       enabled, we won't have collected nothrow information, and if we
*************** output_call_frame_info (int for_eh)
*** 1953,1958 ****
--- 1972,1980 ----
        for (i = 0; i < fde_table_in_use; i++)
  	if (fde_table[i].uses_eh_lsda)
  	  any_eh_needed = any_lsda_needed = true;
+         else if (TARGET_USES_WEAK_UNWIND_INFO
+ 		 && DECL_ONE_ONLY (fde_table[i].decl))
+ 	  any_eh_needed = 1;
  	else if (! fde_table[i].nothrow
  		 && ! fde_table[i].all_throwers_are_sibcalls)
  	  any_eh_needed = true;
*************** output_call_frame_info (int for_eh)
*** 2004,2010 ****
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
--- 2026,2034 ----
  	 P	Indicates the presence of an encoding + language
  		personality routine in the CIE augmentation.  */
  
!       fde_encoding = TARGET_USES_WEAK_UNWIND_INFO && !flag_hidden_one_only
! 	? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1)
! 	: ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
        per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
*************** output_call_frame_info (int for_eh)
*** 2095,2103 ****
--- 2119,2129 ----
        /* Don't emit EH unwind info for leaf functions that don't need it.  */
        if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions
  	  && (fde->nothrow || fde->all_throwers_are_sibcalls)
+ 	  && (! TARGET_USES_WEAK_UNWIND_INFO || ! DECL_ONE_ONLY (fde->decl))
  	  && !fde->uses_eh_lsda)
  	continue;
  
+       (*targetm.asm_out.unwind_label) (asm_out_file, fde->decl, /* empty */ 0);
        (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
        ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
*************** output_call_frame_info (int for_eh)
*** 2113,2121 ****
  
        if (for_eh)
  	{
! 	  dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		   gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		   "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
--- 2139,2154 ----
  
        if (for_eh)
  	{
! 	  if (TARGET_USES_WEAK_UNWIND_INFO
! 	      && DECL_ONE_ONLY (fde->decl))
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER
! 					          (DECL_ASSEMBLER_NAME (fde->decl))),
! 		     "FDE initial location");
! 	  else
! 	    dw2_asm_output_encoded_addr_rtx (fde_encoding,
! 		     gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin),
! 		     "FDE initial location");
  	  dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
  				fde->dw_fde_end, fde->dw_fde_begin,
  				"FDE address range");
*************** dwarf2out_begin_prologue (unsigned int l
*** 2248,2253 ****
--- 2281,2287 ----
  
    /* Add the new FDE at the end of the fde_table.  */
    fde = &fde_table[fde_table_in_use++];
+   fde->decl = current_function_decl;
    fde->dw_fde_begin = xstrdup (label);
    fde->dw_fde_current_label = NULL;
    fde->dw_fde_end = NULL;
Index: gcc/flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.128
diff -p -r1.128 flags.h
*** gcc/flags.h	27 Jan 2004 12:49:30 -0000	1.128
--- gcc/flags.h	1 Feb 2004 05:51:38 -0000
*************** extern int flag_unwind_tables;
*** 505,510 ****
--- 505,515 ----
  
  extern int flag_asynchronous_unwind_tables;
  
+ /* Nonzero means that linkonce symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets.  */
+ 
+ extern int flag_hidden_one_only;
+ 
  /* Nonzero means don't place uninitialized global data in common storage
     by default.  */
  
Index: gcc/output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.135
diff -p -r1.135 output.h
*** gcc/output.h	18 Jan 2004 22:37:27 -0000	1.135
--- gcc/output.h	1 Feb 2004 05:51:39 -0000
*************** extern const char *default_strip_name_en
*** 509,514 ****
--- 509,515 ----
  extern bool default_binds_local_p (tree);
  extern bool default_binds_local_p_1 (tree, int);
  extern void default_globalize_label (FILE *, const char *);
+ extern void default_emit_unwind_label (FILE *, tree, int);
  extern void default_internal_label (FILE *, const char *, unsigned long);
  extern void default_file_start (void);
  extern void file_end_indicate_exec_stack (void);
Index: gcc/target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.66
diff -p -r1.66 target-def.h
*** gcc/target-def.h	31 Jan 2004 22:12:55 -0000	1.66
--- gcc/target-def.h	1 Feb 2004 05:51:39 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 57,62 ****
--- 57,67 ----
  #ifndef TARGET_ASM_GLOBALIZE_LABEL
  #define TARGET_ASM_GLOBALIZE_LABEL default_globalize_label
  #endif
+ 
+ #ifndef TARGET_ASM_EMIT_UNWIND_LABEL
+ #define TARGET_ASM_EMIT_UNWIND_LABEL default_emit_unwind_label
+ #endif
+ 
  #ifndef TARGET_ASM_INTERNAL_LABEL
  #define TARGET_ASM_INTERNAL_LABEL default_internal_label
  #endif
*************** Foundation, 59 Temple Place - Suite 330,
*** 189,194 ****
--- 194,200 ----
  			TARGET_ASM_UNALIGNED_INT_OP,		\
  			TARGET_ASM_INTEGER,			\
  			TARGET_ASM_GLOBALIZE_LABEL,		\
+                         TARGET_ASM_EMIT_UNWIND_LABEL,           \
  			TARGET_ASM_INTERNAL_LABEL,		\
  			TARGET_ASM_ASSEMBLE_VISIBILITY,		\
  			TARGET_ASM_FUNCTION_PROLOGUE,		\
Index: gcc/target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.76
diff -p -r1.76 target.h
*** gcc/target.h	23 Jan 2004 21:05:18 -0000	1.76
--- gcc/target.h	1 Feb 2004 05:51:39 -0000
*************** struct gcc_target
*** 74,79 ****
--- 74,85 ----
      /* Output code that will globalize a label.  */
      void (* globalize_label) (FILE *, const char *);
  
+     /* Output code that will emit a label for unwind info, if this
+        target requires such labels.  Second argument is the decl the
+        unwind info is associated with, third is is a boolean: true if
+        this is only a placeholder for an omitted FDE. */
+     void (* unwind_label ) (FILE *, tree, int);
+ 
      /* Output an internal label.  */
      void (* internal_label) (FILE *, const char *, unsigned long);
  
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.873
diff -p -r1.873 toplev.c
*** gcc/toplev.c	30 Jan 2004 17:43:23 -0000	1.873
--- gcc/toplev.c	1 Feb 2004 05:51:42 -0000
*************** unsigned local_tick;
*** 466,471 ****
--- 466,476 ----
  
  /* -f flags.  */
  
+ /* Nonzero means that linkonce symbols are to be emitted with hidden
+    visiblity.  This is not supported on all targets. */
+ 
+ int flag_hidden_one_only = 0;
+ 
  /* Nonzero means `char' should be signed.  */
  
  int flag_signed_char;
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.408
diff -p -r1.408 varasm.c
*** gcc/varasm.c	31 Jan 2004 23:13:23 -0000	1.408
--- gcc/varasm.c	1 Feb 2004 05:51:45 -0000
*************** globalize_decl (tree decl)
*** 4127,4132 ****
--- 4127,4135 ----
  	}
        return;
      }
+ #elif defined(ASM_MAKE_LABEL_LINKONCE)
+   if (DECL_ONE_ONLY (decl))
+     ASM_MAKE_LABEL_LINKONCE (asm_out_file, name);
  #endif
  
    (*targetm.asm_out.globalize_label) (asm_out_file, name);
*************** make_decl_one_only (tree decl)
*** 4251,4266 ****
  
    TREE_PUBLIC (decl) = 1;
  
!   if (TREE_CODE (decl) == VAR_DECL
!       && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
!     DECL_COMMON (decl) = 1;
!   else if (SUPPORTS_ONE_ONLY)
      {
  #ifdef MAKE_DECL_ONE_ONLY
        MAKE_DECL_ONE_ONLY (decl);
  #endif
        DECL_ONE_ONLY (decl) = 1;
      }
    else if (SUPPORTS_WEAK)
      DECL_WEAK (decl) = 1;
    else
--- 4254,4269 ----
  
    TREE_PUBLIC (decl) = 1;
  
!   if (SUPPORTS_ONE_ONLY)
      {
  #ifdef MAKE_DECL_ONE_ONLY
        MAKE_DECL_ONE_ONLY (decl);
  #endif
        DECL_ONE_ONLY (decl) = 1;
      }
+   else if (TREE_CODE (decl) == VAR_DECL
+       && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
+     DECL_COMMON (decl) = 1;
    else if (SUPPORTS_WEAK)
      DECL_WEAK (decl) = 1;
    else
*************** default_globalize_label (FILE * stream, 
*** 4944,4949 ****
--- 4947,4962 ----
    putc ('\n', stream);
  }
  #endif /* GLOBAL_ASM_OP */
+ 
+ /* Default function to output a label for unwind information.  The
+    default is to do nothing.  A target that needs nonlocal labels for
+    unwind information must provide its own function to do this. */
+ void
+ default_emit_unwind_label (FILE * stream ATTRIBUTE_UNUSED,
+ 			   tree decl ATTRIBUTE_UNUSED,
+ 			   int empty ATTRIBUTE_UNUSED)
+ { 
+ }
  
  /* This is how to output an internal numbered label where PREFIX is
     the class of label and LABELNO is the number within the class.  */
Index: gcc/config/darwin-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin-protos.h,v
retrieving revision 1.29
diff -p -r1.29 darwin-protos.h
*** gcc/config/darwin-protos.h	10 Nov 2003 23:07:09 -0000	1.29
--- gcc/config/darwin-protos.h	1 Feb 2004 05:51:46 -0000
*************** extern void machopic_select_section (tre
*** 73,83 ****
--- 73,92 ----
  extern void machopic_select_rtx_section (enum machine_mode, rtx,
  					 unsigned HOST_WIDE_INT);
  
+ extern void darwin_unique_section (tree decl, int reloc);
+ extern void darwin_asm_named_section (const char *, unsigned int);
+ extern unsigned int darwin_section_type_flags (tree, const char *, int);
+ extern void darwin_non_lazy_pcrel (FILE *, rtx);
+ 
+ extern void darwin_emit_unwind_label(FILE *, tree, int);
+ 
  extern void darwin_pragma_ignore (struct cpp_reader *);
  extern void darwin_pragma_options (struct cpp_reader *);
  extern void darwin_pragma_unused (struct cpp_reader *);
  
  extern void darwin_file_end (void);
+ 
+ extern void darwin_make_decl_one_only (tree decl);
  
  /* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o.  */
  extern void const_section (void);
Index: gcc/config/darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.c,v
retrieving revision 1.55
diff -p -r1.55 darwin.c
*** gcc/config/darwin.c	14 Nov 2003 01:47:55 -0000	1.55
--- gcc/config/darwin.c	1 Feb 2004 05:51:47 -0000
*************** machopic_finish (FILE *asm_out_file)
*** 900,909 ****
        if (! TREE_USED (temp))
  	continue;
  
-       /* If the symbol is actually defined, we don't need a stub.  */
-       if (sym_name[0] == '!' && sym_name[1] == 'T')
- 	continue;
- 
        sym_name = darwin_strip_name_encoding (sym_name);
  
        sym = alloca (strlen (sym_name) + 2);
--- 900,905 ----
*************** darwin_encode_section_info (tree decl, r
*** 1008,1013 ****
--- 1004,1010 ----
    if ((TREE_CODE (decl) == FUNCTION_DECL
         || TREE_CODE (decl) == VAR_DECL)
        && !DECL_EXTERNAL (decl)
+       && (!TREE_PUBLIC (decl) || (!DECL_ONE_ONLY (decl) && !DECL_WEAK (decl)))
        && ((TREE_STATIC (decl)
  	   && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
  	  || (DECL_INITIAL (decl)
*************** update_stubs (const char *name)
*** 1159,1164 ****
--- 1156,1175 ----
  }
  
  void
+ darwin_make_decl_one_only (tree decl)
+ {
+   static const char *text_section = "__TEXT,__textcoal_nt,coalesced,no_toc";
+   static const char *data_section = "__DATA,__datacoal_nt,coalesced,no_toc";
+ 
+   const char *sec = TREE_CODE (decl) == FUNCTION_DECL
+     ? text_section
+     : data_section;
+   TREE_PUBLIC (decl) = 1;
+   DECL_ONE_ONLY (decl) = 1;
+   DECL_SECTION_NAME (decl) = build_string (strlen (sec), sec);
+ }
+ 
+ void
  machopic_select_section (tree exp, int reloc,
  			 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
  {
*************** darwin_globalize_label (FILE *stream, co
*** 1325,1330 ****
--- 1336,1438 ----
      default_globalize_label (stream, name);
  }
  
+ void
+ darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+ {
+   fprintf (asm_out_file, ".section %s\n", name);
+ }
+ 
+ unsigned int
+ darwin_section_type_flags (tree decl, const char *name, int reloc)
+ {
+   unsigned int flags = default_section_type_flags (decl, name, reloc);
+  
+   /* Weak or linkonce variables live in a writable section.  */
+   if (decl != 0 && TREE_CODE (decl) != FUNCTION_DECL
+       && (DECL_WEAK (decl) || DECL_ONE_ONLY (decl)))
+     flags |= SECTION_WRITE;
+   
+   return flags;
+ }              
+ 
+ void 
+ darwin_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
+ {
+   /* Darwin does not use unique sections.  However, the target's
+      unique_section hook is called for linkonce symbols.  We need
+      to set an appropriate section for such symbols. */
+   if (DECL_ONE_ONLY (decl) && !DECL_SECTION_NAME (decl))
+     darwin_make_decl_one_only (decl);
+ }
+ 
+ /* Emit a label for an FDE, making it global and/or weak if appropriate. 
+    The third parameter is nonzero if this is just a placeholder for an
+    FDE that we are omitting. */
+ void 
+ darwin_emit_unwind_label(FILE *file, tree decl, int empty)
+ {
+   tree id = DECL_ASSEMBLER_NAME (decl)
+     ? DECL_ASSEMBLER_NAME (decl)
+     : DECL_NAME (decl);
+ 
+   const char *prefix = "_";
+   const int prefix_len = 1;
+ 
+   const char *base = IDENTIFIER_POINTER (id);
+   unsigned int base_len = IDENTIFIER_LENGTH (id);
+ 
+   const char *suffix = ".eh";
+   unsigned int suffix_len = 3;
+ 
+   int need_quotes = name_needs_quotes (base);
+   int quotes_len = need_quotes ? 2 : 0;
+ 
+   char *lab = xmalloc (prefix_len + base_len + suffix_len + quotes_len + 1);
+   lab[0] = '\0';
+ 
+   if (need_quotes)
+     strcat(lab, "\"");
+   strcat(lab, prefix);
+   strcat(lab, base);
+   strcat(lab, suffix);
+   if (need_quotes)
+     strcat(lab, "\"");
+ 
+   if (TREE_PUBLIC (decl))
+     fprintf (file, "%s %s\n",
+ 	     (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
+ 	      ? ".globl"
+ 	      : ".private_extern"),
+ 	     lab);
+ 
+   if (DECL_ONE_ONLY (decl) && TREE_PUBLIC (decl))
+     fprintf (file, ".weak_definition %s\n", lab);
+ 
+   if (empty)
+     fprintf (file, "%s = 0\n", lab);
+   else
+     fprintf (file, "%s:\n", lab);
+ 
+   free (lab);
+ }
+ 
+ /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */ 
+ void
+ darwin_non_lazy_pcrel (FILE *file, rtx addr)
+ {
+   const char *str;
+   const char *nlp_name;
+ 
+   if (GET_CODE (addr) != SYMBOL_REF)
+     abort ();
+ 
+   str = darwin_strip_name_encoding (XSTR (addr, 0));
+   nlp_name = machopic_non_lazy_ptr_name (str);
+   fputs ("\t.long\t", file);
+   ASM_OUTPUT_LABELREF (file, nlp_name);
+   fputs ("-.", file);
+ }
+ 
  /* Emit an assembler directive to set visibility for a symbol.  The
     only supported visibilities are VISIBILITY_DEFAULT and
     VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
*************** void
*** 1361,1368 ****
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   const char *p = lab1 + (lab1[0] == '*');
!   int islocaldiff = (p[0] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
--- 1469,1476 ----
  darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
  			       const char *lab1, const char *lab2)
  {
!   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
! 		     && lab2[0] == '*' && lab2[1] == 'L');
  
    if (islocaldiff)
      fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.65
diff -p -r1.65 darwin.h
*** gcc/config/darwin.h	26 Dec 2003 19:13:35 -0000	1.65
--- gcc/config/darwin.h	1 Feb 2004 05:51:47 -0000
*************** do { text_section ();							\
*** 310,315 ****
--- 310,356 ----
  	      "\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", "" , N_SO);	\
     } while (0)
  
+ /* Making a symbols weak on Darwin requires more than just setting DECL_WEAK. */
+ #define MAKE_DECL_ONE_ONLY(DECL) darwin_make_decl_one_only (DECL)
+ 
+ /* Representation of linkonce symbols for the MACH-O assembler. Linkonce
+    symbols must be given a special section *and* must be preceded by a 
+    special assembler directive. */
+ #define ASM_MAKE_LABEL_LINKONCE(FILE,  NAME)                            \
+  do { const char* _x = (NAME); if (!!strncmp (_x, "_OBJC_", 6)) {	\
+   fputs (".weak_definition ", FILE); assemble_name (FILE, _x);		\
+   fputs ("\n", FILE); }} while (0)
+ 
+ /* We support hidden visibility */
+ #undef TARGET_SUPPORTS_HIDDEN
+ #define TARGET_SUPPORTS_HIDDEN 1
+ 
+ /* The Darwin linker imposes two limitations on common symbols: they 
+    can't have hidden visibility, and they can't appear in dylibs.  As
+    a consequence, we should never use common symbols to represent 
+    vague linkage. */
+ #undef USE_COMMON_FOR_ONE_ONLY
+ #define USE_COMMON_FOR_ONE_ONLY 0
+ 
+ /* The Darwin linker doesn't like explicit template instantions 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
+ #define TARGET_USES_WEAK_UNWIND_INFO 1
+ 
+ /* We need to use a nonlocal label for the start of an EH frame: the
+    Darwin linker requires that a coalesced section start with a label. */
+ #undef FRAME_BEGIN_LABEL
+ #define FRAME_BEGIN_LABEL "EH_frame"
+ 
+ /* Emit a label for the FDE corresponding to DECL.  EMPTY means 
+    emit a label for an empty FDE. */
+ #define TARGET_ASM_EMIT_UNWIND_LABEL darwin_emit_unwind_label
+ 
  /* Our profiling scheme doesn't LP labels and counter words.  */
  
  #define NO_PROFILE_COUNTERS	1
*************** do { text_section ();							\
*** 361,370 ****
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if ((TREE_STATIC (DECL)						\
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!         || DECL_INITIAL (DECL))						\
!       machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
--- 402,412 ----
      const char *xname = NAME;						\
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)		\
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));			\
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))                   \
!       if ((TREE_STATIC (DECL)						\
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
!           || DECL_INITIAL (DECL))					\
!         machopic_define_name (xname);					\
      if ((TREE_STATIC (DECL)						\
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))		\
          || DECL_INITIAL (DECL))						\
*************** do { text_section ();							\
*** 381,398 ****
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if ((TREE_STATIC (DECL)                                             \
! 	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
!         || DECL_INITIAL (DECL))                                         \
!       machopic_define_name (xname);                                     \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
-     /* Avoid generating stubs for functions we've just defined by	\
-        outputting any required stub name label now.  */			\
-     machopic_output_possible_stub_label (FILE, xname);			\
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
--- 423,438 ----
      const char *xname = NAME;                                           \
      if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF)             \
        xname = IDENTIFIER_POINTER (DECL_NAME (DECL));                    \
!     if (! DECL_ONE_ONLY (DECL) && ! DECL_WEAK (DECL))			\
!       if ((TREE_STATIC (DECL)                                           \
! 	   && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))             \
!           || DECL_INITIAL (DECL))                                       \
!         machopic_define_name (xname);                                   \
      if ((TREE_STATIC (DECL)                                             \
  	 && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL)))               \
          || DECL_INITIAL (DECL))                                         \
        (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false);	\
      ASM_OUTPUT_LABEL (FILE, xname);                                     \
    } while (0)
  
  #define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE)	\
*************** SECTION_FUNCTION (darwin_exception_secti
*** 640,646 ****
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section __TEXT,__eh_frame", 0)	\
  							\
  static void					\
  objc_section_init (void)			\
--- 680,686 ----
  		".section __DATA,__gcc_except_tab", 0)	\
  SECTION_FUNCTION (darwin_eh_frame_section,		\
  		in_darwin_eh_frame,			\
! 		".section " EH_FRAME_SECTION_NAME ",__eh_frame" EH_FRAME_SECTION_ATTR, 0)  \
  							\
  static void					\
  objc_section_init (void)			\
*************** objc_section_init (void)			\
*** 681,686 ****
--- 721,730 ----
  #define TARGET_ASM_SELECT_SECTION machopic_select_section
  #undef	TARGET_ASM_SELECT_RTX_SECTION
  #define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
+ #undef  TARGET_ASM_UNIQUE_SECTION
+ #define TARGET_ASM_UNIQUE_SECTION darwin_unique_section
+ 
+ 
  
  #define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME)			\
      do {								\
*************** enum machopic_addr_class {
*** 808,813 ****
--- 852,860 ----
  
  #define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
  
+ #define EH_FRAME_SECTION_NAME   "__TEXT"
+ #define EH_FRAME_SECTION_ATTR ",coalesced,no_toc+strip_static_syms"
+ 
  #undef ASM_PREFERRED_EH_DATA_FORMAT
  #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)  \
    (((CODE) == 2 && (GLOBAL) == 1) \
*************** enum machopic_addr_class {
*** 817,823 ****
--- 864,882 ----
  #define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
    darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
  
+ #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE)	\
+       if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) {				\
+ 	darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR);					\
+ 	goto DONE;									\
+       }
+ 
+ 
  #define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
+ 
+ #undef TARGET_ASM_NAMED_SECTION
+ #define TARGET_ASM_NAMED_SECTION darwin_asm_named_section
+ #undef TARGET_SECTION_TYPE_FLAGS
+ #define TARGET_SECTION_TYPE_FLAGS darwin_section_type_flags
  
  #define DARWIN_REGISTER_TARGET_PRAGMAS()			\
    do {								\
Index: gcc/cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3923
diff -p -r1.3923 ChangeLog
*** gcc/cp/ChangeLog	31 Jan 2004 17:58:46 -0000	1.3923
--- gcc/cp/ChangeLog	1 Feb 2004 05:51:48 -0000
***************
*** 1,3 ****
--- 1,19 ----
+ 2004-01-31  Matt Austern  <austern@apple.com>
+ 
+ 	* decl2.c (comdat_linkage): Set visibility of weak symbols to
+ 	VISIBLITY_HIDDEN if user sets the appropriate flag.
+ 	(maybe_make_one_only): Likewise.  Also, look at
+ 	TARGET_EXPLICIT_INSTANTIATION_ONE_ONLY when deciding whether to
+ 	make an explicit instantiation weak.
+ 	(maybe_emit_vtables): If weak symbols are hidden, be more
+ 	cautious about making vtables weak.
+ 	* method.c (make_thunk): If weak symbols are hidden, be more
+ 	cautious about making thunks weak.
+ 	(use_thunk): Ditto.
+ 	* pt.c (do_type_instantiation): On systems where weak symbols
+ 	don't go in a static archive's TOC, explicit instantiation of a
+ 	class must imply *explicit* instantiation of its memeber.
+ 	
  2004-01-31  Kazu Hirata  <kazu@cs.umass.edu>
  
  	* class.c: Fix comment typos.
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.697
diff -p -r1.697 decl2.c
*** gcc/cp/decl2.c	26 Jan 2004 17:41:50 -0000	1.697
--- gcc/cp/decl2.c	1 Feb 2004 05:51:50 -0000
*************** void
*** 1359,1365 ****
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     make_decl_one_only (decl);
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
--- 1359,1369 ----
  comdat_linkage (tree decl)
  {
    if (flag_weak)
!     {
!       make_decl_one_only (decl);
!       if (flag_hidden_one_only)
! 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
!     }
    else if (TREE_CODE (decl) == FUNCTION_DECL 
  	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
      /* We can just emit function and compiler-generated variables
*************** comdat_linkage (tree decl)
*** 1406,1412 ****
  
  /* For win32 we also want to put explicit instantiations in
     linkonce sections, so that they will be merged with implicit
!    instantiations; otherwise we get duplicate symbol errors.  */
  
  void
  maybe_make_one_only (tree decl)
--- 1410,1418 ----
  
  /* For win32 we also want to put explicit instantiations in
     linkonce sections, so that they will be merged with implicit
!    instantiations; otherwise we get duplicate symbol errors.  
!    For Darwin we do not want explicit instantiations to be 
!    linkonce. */
  
  void
  maybe_make_one_only (tree decl)
*************** maybe_make_one_only (tree decl)
*** 1425,1437 ****
       to for variables so that cp_finish_decl will update their linkage,
       because their DECL_INITIAL may not have been set properly yet.  */
  
!   make_decl_one_only (decl);
! 
!   if (TREE_CODE (decl) == VAR_DECL)
      {
!       DECL_COMDAT (decl) = 1;
!       /* Mark it needed so we don't forget to emit it.  */
!       mark_referenced (DECL_ASSEMBLER_NAME (decl));
      }
  }
  
--- 1431,1450 ----
       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)))
      {
!       make_decl_one_only (decl);
!       if (flag_hidden_one_only)
! 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
! 
!       if (TREE_CODE (decl) == VAR_DECL)
! 	{
! 	  DECL_COMDAT (decl) = 1;
! 	  /* Mark it needed so we don't forget to emit it.  */
! 	  mark_referenced (DECL_ASSEMBLER_NAME (decl));
! 	}
      }
  }
  
*************** maybe_emit_vtables (tree ctype)
*** 1561,1566 ****
--- 1574,1580 ----
    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)
*** 1591,1596 ****
--- 1605,1631 ----
    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: on systems where we don't have weak symbols
+      (obviously), and if weak symbols are given hidden visibility.  In
+      the latter case we make vtables weak only in cases where they
+      really will be emitted in multiple translation units, not in the
+      more common case where we're emitting the vtable in the
+      translation unit containing the definition of a noninline key
+      method. */
+   if (flag_weak && !flag_hidden_one_only)
+     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)
*** 1637,1644 ****
  	  DECL_IGNORED_P (vtbl) = 1;
  	}
  
!       /* Always make vtables weak.  */
!       if (flag_weak)
  	comdat_linkage (vtbl);
  
        rest_of_decl_compilation (vtbl, NULL, 1, 1);
--- 1672,1679 ----
  	  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/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.276
diff -p -r1.276 method.c
*** gcc/cp/method.c	30 Jan 2004 23:37:39 -0000	1.276
--- gcc/cp/method.c	1 Feb 2004 05:51:51 -0000
*************** make_thunk (tree function, bool this_adj
*** 153,160 ****
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
    if (flag_weak)
!     comdat_linkage (thunk);
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
--- 153,167 ----
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
+ 
+   /* Always make thunks weak.  Or at least *almost* always.  If weak
+      symbols may be given hidden visibility, we have to be more careful. */
    if (flag_weak)
!     if (!flag_hidden_one_only
! 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
! 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
!       comdat_linkage (thunk);
! 
    SET_DECL_THUNK_P (thunk, this_adjusting);
    THUNK_TARGET (thunk) = function;
    THUNK_FIXED_OFFSET (thunk) = d;
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 390,395 ****
--- 397,407 ----
       rewrite.  */
    TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
    DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
+   if (flag_weak)
+     if (!flag_hidden_one_only
+ 	|| DECL_ONE_ONLY (function) || DECL_WEAK (function)
+ 	|| DECL_VISIBILITY (function) == VISIBILITY_HIDDEN)
+       comdat_linkage (thunk_fndecl);
  
    if (flag_syntax_only)
      {
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.822
diff -p -r1.822 pt.c
*** gcc/cp/pt.c	31 Jan 2004 17:58:53 -0000	1.822
--- gcc/cp/pt.c	1 Feb 2004 05:51:58 -0000
*************** do_type_instantiation (tree t, tree stor
*** 10576,10581 ****
--- 10576,10582 ----
    int extern_p = 0;
    int nomem_p = 0;
    int static_p = 0;
+   int previous_instantiation_extern_p = 0;
  
    if (TREE_CODE (t) == TYPE_DECL)
      t = TREE_TYPE (t);
*************** do_type_instantiation (tree t, tree stor
*** 10637,10647 ****
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation
! 	 was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
! 	 are we already got marked as an explicit instantiation because of the
! 	 repo file.  All these cases are OK.  */
!       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
--- 10638,10653 ----
  	 No program shall explicitly instantiate any template more
  	 than once.  
  
!          If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
! 	 instantiation was `extern'.  If EXTERN_P then the second is.
! 	 If -frepo, chances are we already got marked as an explicit
! 	 instantiation because of the repo file.  All these cases are
! 	 OK.  */
! 
!       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
! 
!       if (!previous_instantiation_extern_p && !extern_p
! 	  && !flag_use_repository
  	  && (complain & tf_error))
  	pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
*************** do_type_instantiation (tree t, tree stor
*** 10658,10663 ****
--- 10664,10670 ----
  
    {
      tree tmp;
+     int explicitly_instantiate_members = 0;
  
      /* In contrast to implicit instantiation, where only the
         declarations, and not the definitions, of members are
*************** do_type_instantiation (tree t, tree stor
*** 10676,10701 ****
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  */
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    mark_decl_instantiated (tmp, extern_p);
! 	    repo_template_instantiated (tmp, extern_p);
! 	    if (! extern_p)
! 	      instantiate_decl (tmp, /*defer_ok=*/1);
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  mark_decl_instantiated (tmp, extern_p);
! 	  repo_template_instantiated (tmp, extern_p);
! 	  if (! extern_p)
! 	    instantiate_decl (tmp, /*defer_ok=*/1);
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
--- 10683,10728 ----
         *explicit* instantiations or not.  We choose to be generous,
         and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
         the explicit instantiation of a class where some of the members
!        have no definition in the current translation unit.  Exception:
!        on some targets (e.g. Darwin), weak symbols do not get put in 
!        a static archive's TOC.  The problematic case is if we're doing
!        a non-extern explicit instantiation of an extern template: we
!        have to put member functions in the TOC in that case, or we'll
!        get unresolved symbols at link time. */
! 
!     explicitly_instantiate_members =
!       TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
!       && previous_instantiation_extern_p && ! extern_p
!       && ! TYPE_FOR_JAVA (t);
  
      if (! static_p)
        for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
  	if (TREE_CODE (tmp) == FUNCTION_DECL
  	    && DECL_TEMPLATE_INSTANTIATION (tmp))
  	  {
! 	    if (explicitly_instantiate_members)
! 	      do_decl_instantiation (tmp, NULL_TREE);
! 	    else
! 	      {
! 		mark_decl_instantiated (tmp, extern_p);
! 		repo_template_instantiated (tmp, extern_p);
! 		if (! extern_p)
! 		  instantiate_decl (tmp, /*defer_ok=*/1);
! 	      }
  	  }
  
      for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
  	{
! 	  if (explicitly_instantiate_members)
! 	    do_decl_instantiation (tmp, NULL_TREE);
! 	  else
! 	    {
! 	      mark_decl_instantiated (tmp, extern_p);
! 	      repo_template_instantiated (tmp, extern_p);
! 	      if (! extern_p)
! 		instantiate_decl (tmp, /*defer_ok=*/1);
! 	    }
  	}
  
      if (CLASSTYPE_NESTED_UTDS (t))
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.400
diff -p -r1.400 invoke.texi
*** gcc/doc/invoke.texi	31 Jan 2004 20:09:22 -0000	1.400
--- gcc/doc/invoke.texi	1 Feb 2004 05:52:08 -0000
*************** in the following sections.
*** 182,188 ****
  -fno-nonansi-builtins  -fno-operator-names @gol
  -fno-optional-diags  -fpermissive @gol
  -frepo  -fno-rtti  -fstats  -ftemplate-depth-@var{n} @gol
! -fuse-cxa-atexit  -fno-weak  -nostdinc++ @gol
  -fno-default-inline  -Wabi  -Wctor-dtor-privacy @gol
  -Wnon-virtual-dtor  -Wreorder @gol
  -Weffc++  -Wno-deprecated @gol
--- 182,188 ----
  -fno-nonansi-builtins  -fno-operator-names @gol
  -fno-optional-diags  -fpermissive @gol
  -frepo  -fno-rtti  -fstats  -ftemplate-depth-@var{n} @gol
! -fuse-cxa-atexit  -fno-weak -fhidden-one-only -nostdinc++ @gol
  -fno-default-inline  -Wabi  -Wctor-dtor-privacy @gol
  -Wnon-virtual-dtor  -Wreorder @gol
  -Weffc++  -Wno-deprecated @gol
*************** By default, G++ will use weak symbols if
*** 1440,1445 ****
--- 1440,1453 ----
  option exists only for testing, and should not be used by end-users;
  it will result in inferior code and has no benefits.  This option may
  be removed in a future release of G++.
+ 
+ @item -fhidden-one-only
+ @opindex fhidden-one-only
+ Give hidden visibility to all symbols that the compiler emits with
+ one-only linkage, such as implicit template instantiations.  This
+ option does not affect the visibility of symbols that the user
+ explicitly declares weak.  If the target does not support both
+ linkonce symbols and hidden visibility, this option is ignored.
  
  @item -nostdinc++
  @opindex nostdinc++
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.289
diff -p -r1.289 tm.texi
*** gcc/doc/tm.texi	31 Jan 2004 17:31:40 -0000	1.289
--- gcc/doc/tm.texi	1 Feb 2004 05:52:17 -0000
*************** for the abi and context in the @code{.un
*** 3072,3077 ****
--- 3072,3083 ----
  be updated in @var{fs}.
  @end defmac
  
+ @defmac TARGET_USES_WEAK_UNWIND_INFO
+ A C expression that evaluates to true if the target requires unwind
+ info to be given comdat linkage.  Define it to be @code{1} if comdat
+ linkage is necessary.  The default is @code{0}.
+ @end defmac
+ 
  @node Stack Checking
  @subsection Specifying How Stack Checking is Done
  
*************** commands that will make the symbol(s) as
*** 6736,6741 ****
--- 6742,6764 ----
  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}.  Define this macro
+ if explicit and implicit template specialization should be treated
+ differently.
+ @end defmac
+ 
+ @defmac TARGET_SUPPORTS_HIDDEN
+ A C expression that evaluates to true if the target supports hidden
+ visibility.  By default this expression is true if and only if
+ @code{HAS_GAS_HIDDEN} is defined.  Set this macro if the
+ @code{HAS_GAS_HIDDEN} macro gives the wrong answer for this
+ target.  (For example, if the target's mechanism for supporting
+ hidden visibility is not the same as GAS's.)
+ @end defmac
+ 
  @defmac ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
  A C statement (sans semicolon) to output to the stdio stream
  @var{stream} any text necessary for declaring the name of an external
*************** of the preceding label.
*** 7457,7462 ****
--- 7480,7496 ----
  If this macro is not defined, nothing special is output at the end of
  the jump-table.
  @end defmac
+ 
+ @deftypefn {Target Hook} void TARGET_ASM_EMIT_UNWIND_LABEL (@var{stream}, @var{decl}, @var{empty})
+ This target hook emits a label at the beginning of each FDE.  It
+ should be defined on targets where FDEs need special labels, and it
+ should write the appropriate label, for the FDE associated with the
+ function declaration @var{decl}, to the stdio stream @var{stream}.
+ The third argument, @var{empty}, is a boolean: true if this is a
+ placeholder label for an omitted FDE.
+ 
+ The default is that FDEs are not given nonlocal labels.
+ @end deftypefn
  
  @node Exception Region Output
  @subsection Assembler Commands for Exception Regions
Index: gcc/testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.3447
diff -p -r1.3447 ChangeLog
*** gcc/testsuite/ChangeLog	31 Jan 2004 09:49:12 -0000	1.3447
--- gcc/testsuite/ChangeLog	1 Feb 2004 05:52:27 -0000
***************
*** 1,3 ****
--- 1,23 ----
+ 2004-01-31  Matt Austern  <austern@apple.com>
+ 	* g++.dg/other/hidden-weak-1.C: New test.
+ 	* g++.dg/other/hidden-weak-2.C: Likewise.
+ 	* g++.dg/other/hidden-weak-3.C: Likewise.
+ 	* g++.dg/other/hidden-weak-4.C: Likewise.
+ 	* g++.dg/other/hidden-weak-5.C: Likewise.
+ 	* g++.dg/other/hidden-weak-6.C: Likewise.
+ 	* g++.dg/other/hidden-weak-7.C: Likewise.
+ 	* g++.dg/other/hidden-weak-8.C: Likewise.
+ 	* g++.dg/other/hidden-weak-9.C: Likewise.
+ 	* g++.dg/other/hidden-weak-10.C: Likewise.
+ 	* g++.dg/other/hidden-weak-11.C: Likewise.
+ 	* g++.dg/other/hidden-weak-12.C: Likewise.
+ 	* g++.dg/other/hidden-weak-13.C: Likewise.
+ 	* g++.dg/other/hidden-weak-14.C: Likewise.
+ 	* g++.dg/other/hidden-weak-15.C: Likewise.
+ 	* g++.dg/other/hidden-weak-16.C: Likewise.
+ 	* g++.dg/other/hidden-weak-17.C: Likewise.
+ 	* g++.dg/other/hidden-weak-18.C: Likewise.
+ 	
  2004-01-30  Andrew Pinski  <pinskia@physics.uc.edu>
  
  	* objc.dg/call-super-2.m: Update line numbers
Index: gcc/testsuite/g++.dg/other/hidden-weak-1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-1.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-1.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Implicit instantiation of function template in presence of -fhidden-one-only
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-10.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-10.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-10.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-10.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Inline function in presence of -fhidden-one-only
+ 
+ inline long fact(long n)
+ {
+   return n <= 0 ? 1 : n * fact(n-1);
+ }
+ 
+ int main()
+ {
+   long result = fact(6);
+   return result == 720 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-11.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-11.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-11.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-11.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z8identityIiET_S0_" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z8identityIiET_S0_" } }
+ 
+ // Implicit instantiation of function template in presence of -fhidden-one-only
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-12.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-12.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-12.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-12.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,26 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z5xyzzyIiET_S0_" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z5xyzzyIiET_S0_" } }
+ 
+ // Implicit instantiation of function template with static local variable in 
+ // the presence of -fhidden-one-only
+ 
+ template <typename X>
+ X xyzzy (X x)
+ {
+   static bool first = true;
+   static X first_x;
+   if (first)
+     first_x = x;
+   first = false;
+   return first_x;
+ }
+ 
+ int main()
+ {
+   xyzzy(17);
+   return (xyzzy(39) == 17) ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-13.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-13.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-13.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-13.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,41 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ // { dg-final { scan-assembler "\\.weak_definition __ZNK7wrapperIlE3getEv" } }
+ // { dg-final { scan-assembler "\\.private_extern __ZNK7wrapperIlE3getEv" } }
+ 
+ // Implicit instantiation of class template with -fhidden-one-only
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   template <typename Y> wrapper(const Y& y);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ template <typename Y>
+ wrapper<X>::wrapper(const Y& y)
+   : val(y)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ int main()
+ {
+   wrapper<long> tmp(17);
+   return tmp.get() == 17l ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-14.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-14.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-14.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-14.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,25 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ // { dg-final { scan-assembler "\\.weak_definition __ZN1AIiE3arrE" } }
+ // { dg-final { scan-assembler "\\.private_extern __ZN1AIiE3arrE" } }
+ 
+ // Implicit instantiation of class template with static array
+ // in the presence of -fhidden-one-only
+ 
+ template <typename X>
+ struct A
+ {
+   static X arr[2];
+ };
+ 
+ template <typename X>
+ X A<X>::arr[2] = { 13, 45 };
+ 
+ int main()
+ {
+   bool ok = true;
+   ok = ok && A<int>::arr[0] == 13;
+   ok = ok && A<int>::arr[1] == 45;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-15.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-15.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-15.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-15.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do compile { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ // { dg-final { scan-assembler "\\.weak_definition __Z4factl" } }
+ // { dg-final { scan-assembler "\\.private_extern __Z4factl" } }
+ 
+ // Inline function in presence of -fhidden-one-only
+ 
+ inline long fact(long n)
+ {
+   return n <= 0 ? 1 : n * fact(n-1);
+ }
+ 
+ int main()
+ {
+   long result = fact(6);
+   return result == 720 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-2.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-2.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-2.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,24 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Implicit instantiation of function template with static local variable in 
+ // the presence of -fhidden-one-only
+ 
+ template <typename X>
+ X xyzzy (X x)
+ {
+   static bool first = true;
+   static X first_x;
+   if (first)
+     first_x = x;
+   first = false;
+   return first_x;
+ }
+ 
+ int main()
+ {
+   xyzzy(17);
+   return (xyzzy(39) == 17) ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-3.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-3.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-3.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,39 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Implicit instantiation of class template with -fhidden-one-only
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   template <typename Y> wrapper(const Y& y);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ template <typename Y>
+ wrapper<X>::wrapper(const Y& y)
+   : val(y)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ int main()
+ {
+   wrapper<long> tmp(17);
+   return tmp.get() == 17l ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-4.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-4.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-4.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,40 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Implicit instantiation of class template with static member variable
+ // in the presence of -fhidden-one-only
+ 
+ template <typename X>
+ struct wrapper
+ {
+   wrapper();
+   virtual ~wrapper();
+   static X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper()
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ X wrapper<X>::val = 86;
+ 
+ int main()
+ {
+   wrapper<long> tmp;
+   bool ok = true;
+   ok = ok && tmp.val == 86;
+ 
+   tmp.val = 7;
+   wrapper<long> tmp2;
+   ok = ok && tmp2.val == 7;
+   ok = ok && wrapper<char>::val == 86;
+ 
+   return !ok;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-5.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-5.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-5.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,23 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Implicit instantiation of class template with static array
+ // in the presence of -fhidden-one-only
+ 
+ template <typename X>
+ struct A
+ {
+   static X arr[2];
+ };
+ 
+ template <typename X>
+ X A<X>::arr[2] = { 13, 45 };
+ 
+ int main()
+ {
+   bool ok = true;
+   ok = ok && A<int>::arr[0] == 13;
+   ok = ok && A<int>::arr[1] == 45;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-6.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-6.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-6.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Explicit instantiation of function template with -fhidden-one-only
+ 
+ template <typename X>
+ X identity (X x)
+ {
+   return x;
+ }
+ 
+ template int identity(int);
+ 
+ int main()
+ {
+   return identity(0);
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-7.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-7.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-7.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-7.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,40 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Explicit instantiation of class template with -fhidden-one-only
+ 
+ template <typename X>
+ struct wrapper
+ {
+ public:
+   wrapper(const X& x);
+   virtual ~wrapper();
+   const X& get() const;
+ private:
+   X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper(const X& x)
+   : val(x)
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ const X& wrapper<X>::get() const
+ {
+   return val;
+ }
+ 
+ template struct wrapper<int>;
+ 
+ int main()
+ {
+   wrapper<int> tmp(17);
+   return tmp.get() == 17 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-8.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-8.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-8.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,33 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Explicit instantiation of class template with static member variable
+ // in the presence of -fhidden-one-only
+ 
+ template <typename X>
+ struct wrapper
+ {
+   wrapper();
+   virtual ~wrapper();
+   static X val;
+ };
+ 
+ template <typename X>
+ wrapper<X>::wrapper()
+ { }
+ 
+ template <typename X>
+ wrapper<X>::~wrapper()
+ { }
+ 
+ template <typename X>
+ X wrapper<X>::val = 86;
+ 
+ template struct wrapper<int>;
+ 
+ int main()
+ {
+   return wrapper<int>::val == 86 ? 0 : 1;
+ }
Index: gcc/testsuite/g++.dg/other/hidden-weak-9.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/hidden-weak-9.C
diff -N gcc/testsuite/g++.dg/other/hidden-weak-9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/hidden-weak-9.C	1 Feb 2004 05:52:30 -0000
***************
*** 0 ****
--- 1,22 ----
+ // Copyright (C) 2004  Free Software Foundation.
+ // Contributed by Matt Austern <austern@apple.com> 20 Jan 2004
+ // { dg-do run { target powerpc-apple-darwin* } }
+ // { dg-options "-fhidden-one-only" }
+ 
+ // Polymorphic class with no key method in the presence of -fhidden-one-only
+ 
+ struct X
+ {
+ public:
+   X(int n) : val(n) { }
+   virtual ~X() { }
+   virtual int get() const { return val; }
+ private:
+   int val;
+ };
+ 
+ int main()
+ {
+   X* pX = new X(13);
+   return pX->get() == 13 ? 0 : 1;
+ }
Index: libffi/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libffi/ChangeLog,v
retrieving revision 1.157
diff -p -r1.157 ChangeLog
*** libffi/ChangeLog	25 Jan 2004 06:58:33 -0000	1.157
--- libffi/ChangeLog	1 Feb 2004 05:52:35 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2004-01-31  Matt Austern  <austern@apple.com>
+ 	* src/powerpc/darwin.S: Change EH information in assembly glue to
+ 	match EH format changes in the compiler.
+ 	* src/powerpc/darwin_closure.S: Ditto.
+ 	
  2004-01-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
  
  	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
Index: libffi/src/powerpc/darwin.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin.S,v
retrieving revision 1.7
diff -p -r1.7 darwin.S
*** libffi/src/powerpc/darwin.S	21 Oct 2003 19:01:56 -0000	1.7
--- libffi/src/powerpc/darwin.S	1 Feb 2004 05:52:36 -0000
*************** _ffi_call_AIX:
*** 162,169 ****
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 162,169 ----
  /* END(_ffi_call_AIX)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 173,191 ****
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte   0x1     ; uleb128 0x1; Augmentation size
! 	.byte   0x10    ; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
--- 173,192 ----
  	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
! 	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_call_DARWIN.eh
+ _ffi_call_DARWIN.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  LASFDE1:
! 	.long	LASFDE1-EH_frame1 ; FDE CIE offset
  	.long	LFB0-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB0
  	.long	L$set$3	; FDE address range
Index: libffi/src/powerpc/darwin_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin_closure.S,v
retrieving revision 1.6
diff -p -r1.6 darwin_closure.S
*** libffi/src/powerpc/darwin_closure.S	18 Sep 2003 19:35:46 -0000	1.6
--- libffi/src/powerpc/darwin_closure.S	1 Feb 2004 05:52:36 -0000
*************** Lfinish:
*** 234,241 ****
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame
! Lframe1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
--- 234,241 ----
  /* END(ffi_closure_ASM)  */
  
  .data
! .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
! EH_frame1:
  	.set	L$set$0,LECIE1-LSCIE1
  	.long	L$set$0	; Length of Common Information Entry
  LSCIE1:
*************** LSCIE1:
*** 246,264 ****
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x10	; FDE Encoding (pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.set	L$set$2,LASFDE1-Lframe1
! 	.long	L$set$2	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range
--- 246,265 ----
  	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
  	.byte	0x41	; CIE RA Column
  	.byte	0x1	; uleb128 0x1; Augmentation size
! 	.byte	0x90	; FDE Encoding (indirect pcrel)
  	.byte	0xc	; DW_CFA_def_cfa
  	.byte	0x1	; uleb128 0x1
  	.byte	0x0	; uleb128 0x0
  	.align	2
  LECIE1:
+ .globl _ffi_closure_ASM.eh
+ _ffi_closure_ASM.eh:
  LSFDE1:
  	.set	L$set$1,LEFDE1-LASFDE1
  	.long	L$set$1	; FDE Length
  
  LASFDE1:
! 	.long	LASFDE1-EH_frame1	; FDE CIE offset
  	.long	LFB1-.	; FDE initial location
  	.set	L$set$3,LFE1-LFB1
  	.long	L$set$3	; FDE address range

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-30 21:19 ` Matt Austern
@ 2004-01-30 21:49   ` Kevin B. Hendricks
  0 siblings, 0 replies; 17+ messages in thread
From: Kevin B. Hendricks @ 2004-01-30 21:49 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc

Hi Matt,

> But a general comment: this is exactly the sort of reason I wanted to
> redo coalescing, design it  more carefully, and get it into the GNU
> compiler.  I want to make sure that this is well tested, that it's
> reviewed by people outside Apple, and that it's not a set of ad hoc
> patches that have to get redone every time Apple does an import from
> the GNU repository.  If I introduce any coalescing bugs in the GNU
> mainline, I'll fix them. Apple quite aware that coalescing has been
> less reliable than it ought to be, and that's exactly what this is
> supposed to address.

Undestood.  We do have a (very large!) testcase and if and when this patch is 
approved and committed to mainline, I will build it on MacOSX and try our 
testcase and let you know if any problems are detected.

> (The reason you didn't see coalescing bugs in the mainline Darwin
> compiler is that it didn't have linkonce semantics at all. When you
> instantiated a template in multiple translation units, you'd get
> separate copies in each ones.  This breaks an awful lot of things.
> Linkonce semantics aren't just an optimization, they're required for
> correctness.)

Thanks for explaining that.  I did not realize that the current GNU Darwin 
compiler was considered "broken" in that regard.  The funny thing is STLport 
uses lots of templates instantiated in different modules but GNU Darwin 
passed the stlport tests with flying colors.  I guess the tests simply did 
not detect the fact that separate copies were being generated.

Kevin

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
  2004-01-30 19:27 Kevin B. Hendricks
@ 2004-01-30 21:19 ` Matt Austern
  2004-01-30 21:49   ` Kevin B. Hendricks
  0 siblings, 1 reply; 17+ messages in thread
From: Matt Austern @ 2004-01-30 21:19 UTC (permalink / raw)
  To: Kevin B. Hendricks; +Cc: gcc

On Jan 30, 2004, at 11:16 AM, Kevin B. Hendricks wrote:

> Hi Matt,
>
> A quick general question about this patch, the OpenOffice.org porters 
> to MacOSX ran into serious problems with "coalesced" symbols that were 
> not fixed until the most recent Apple version of GCC 3.3.  The problem 
> was most easily seen when linking in libstlport (STL) and finding that 
> depending on the mix of the compiler optimization levels used we 
> generated strange linker failures related to coalesced symbols not 
> being present in each linker section (or only in the wrong section?)
>
> For example, rebuilding one library with -O0 -g for debugging purposes 
> seemed to create problems when trying to link with other libraries 
> that typically did not exist if everything was compiled at -O2 or 
> higher.  Typically the error message looked like the following:
>
> > ./STLport-4.5/lib/libstlport_gcc.dylib)
> > ld: huh.o illegal reference for -dynamic code (section difference
> > reference from section (__TEXT,__eh_frame) relocation entry (82) to
> > symbol: _STL::__node_alloc<(bool)1, (int)0>::allocate(unsigned long)
> > defined in dylib: ./STLport-4.5/lib/libstlport_gcc.dylib)
>
> The GNU Darwin compiler gcc 3.3 *never* seemed to have the same 
> problems at that time that the Apple compiler had until the August gcc 
> 3.3 update (but it did have problems with static objects in templates 
> and other issues).
>
> Has this problem of mixing optimization levels and potentially missing 
> related coalesced been tested in the new Darwin build with your patch 
> in place to make sure the same problem that existed until recently in 
> Apple's gcc 3.3 is not being introduced mistakenly into Darwin?

I haven't put any test cases like that into the dg test suite, because 
I'm not enough of a dg expert to know how to write complicated test 
cases that involve multiple dylibs.  If anyone can point me to a 
"writing complicated dg test cases for dummies" tutorial, I'll write 
better tests.

But a general comment: this is exactly the sort of reason I wanted to 
redo coalescing, design it  more carefully, and get it into the GNU 
compiler.  I want to make sure that this is well tested, that it's 
reviewed by people outside Apple, and that it's not a set of ad hoc 
patches that have to get redone every time Apple does an import from 
the GNU repository.  If I introduce any coalescing bugs in the GNU 
mainline, I'll fix them. Apple quite aware that coalescing has been 
less reliable than it ought to be, and that's exactly what this is 
supposed to address.

(The reason you didn't see coalescing bugs in the mainline Darwin 
compiler is that it didn't have linkonce semantics at all. When you 
instantiated a template in multiple translation units, you'd get 
separate copies in each ones.  This breaks an awful lot of things.  
Linkonce semantics aren't just an optimization, they're required for 
correctness.)

			--Matt

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

* Re: [Darwin] Patch, take 2: enable linkonce support for Darwin
@ 2004-01-30 19:27 Kevin B. Hendricks
  2004-01-30 21:19 ` Matt Austern
  0 siblings, 1 reply; 17+ messages in thread
From: Kevin B. Hendricks @ 2004-01-30 19:27 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc

Hi Matt,

A quick general question about this patch, the OpenOffice.org porters 
to MacOSX ran into serious problems with "coalesced" symbols that were 
not fixed until the most recent Apple version of GCC 3.3.  The problem 
was most easily seen when linking in libstlport (STL) and finding that 
depending on the mix of the compiler optimization levels used we 
generated strange linker failures related to coalesced symbols not 
being present in each linker section (or only in the wrong section?)

For example, rebuilding one library with -O0 -g for debugging purposes 
seemed to create problems when trying to link with other libraries that 
typically did not exist if everything was compiled at -O2 or higher.  
Typically the error message looked like the following:

 > ./STLport-4.5/lib/libstlport_gcc.dylib)
 > ld: huh.o illegal reference for -dynamic code (section difference
 > reference from section (__TEXT,__eh_frame) relocation entry (82) to
 > symbol: _STL::__node_alloc<(bool)1, (int)0>::allocate(unsigned long)
 > defined in dylib: ./STLport-4.5/lib/libstlport_gcc.dylib)

The GNU Darwin compiler gcc 3.3 *never* seemed to have the same 
problems at that time that the Apple compiler had until the August gcc 
3.3 update (but it did have problems with static objects in templates 
and other issues).

Has this problem of mixing optimization levels and potentially missing 
related coalesced been tested in the new Darwin build with your patch 
in place to make sure the same problem that existed until recently in 
Apple's gcc 3.3 is not being introduced mistakenly into Darwin?

I guess I am just being paranoid but that problem held up progress for 
us almost 2 years.  :-)

Now if we could just get the C++ static initialization to work reliably 
(I have a test case in case anyone is interested which shows static 
initialization of an object being re-entered in a single threaded app 
unless -bind_at_load or -single-module is used which horribly slows 
down the startup time of OpenOffice.org).  Please see the following url 
if interested.

http://porting.openoffice.org/servlets/ReadMsg?list=dev&msgId=916562

Thanks,

Kevin





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

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

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-29 17:42 [Darwin] Patch: enable linkonce support for Darwin Matt Austern
2004-01-30 16:53 ` [Darwin] Patch, take 2: " Matt Austern
2004-01-31  0:05   ` Richard Henderson
2004-01-31  1:20     ` Matt Austern
2004-02-02 18:47       ` Jason Merrill
2004-02-02 19:00         ` Matt Austern
2004-02-02 19:12           ` Jason Merrill
2004-02-02 23:30             ` Matt Austern
2004-02-03 22:11             ` -fhidden-one-only and the EH runtime Matt Austern
2004-02-02 22:39           ` [Darwin] Patch, take 2: enable linkonce support for Darwin Mike Stump
2004-02-02 22:55             ` Matt Austern
2004-02-02 23:26               ` Mike Stump
2004-02-02 23:40               ` Jason Merrill
2004-01-30 19:27 Kevin B. Hendricks
2004-01-30 21:19 ` Matt Austern
2004-01-30 21:49   ` Kevin B. Hendricks
2004-02-01  5:53 Matt Austern

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