diff mbox

PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking

Message ID 20150207122739.GA25185@gmail.com
State New
Headers show

Commit Message

H.J. Lu Feb. 7, 2015, 12:27 p.m. UTC
On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
> H.J.,
>      The new patch bootstraps okay on x86_64-apple-darwin14 but I

Does it cause any regressions on x86_64-apple-darwin14?

> discovered that you need a small adjustment in the deja-gnu
> statements...
> 
>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
> 2015-02-06 21:45:04.000000000 -0500
> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
> 2015-02-07 03:24:42.000000000 -0500
> @@ -8,9 +8,9 @@
>  /* For kernel modules and static RTPs, the loader treats undefined weak
>     symbols in the same way as undefined strong symbols.  The test
>     therefore fails to load, so skip it.  */
> +/* { dg-options "-fPIC" { target fpic } } */
>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
> *-*-darwin* } } */
>  /* { dg-additional-options "-Wl,-flat_namespace" { target
> *-*-darwin[89]* } } */
> -/* { dg-options "-fPIC" { target fpic } } */
> 
>  extern void foo () __attribute__((weak,visibility("hidden")));
>  int
> 
> If you don't define a dg-options line first, the dg-additional-options
> lines have no effect.
>                  Jack

Here is the updated patch.

H.J.
---
From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 5 Feb 2015 14:28:58 -0800
Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC

If a hidden weak symbol isn't defined in the TU, we can't assume it will
be defined in another TU at link time.  It makes a difference in code
generation when compiling for PIC. If we assume that a hidden weak
undefined symbol is local, the address checking may be optimized out and
leads to the wrong code.  This means that a symbol with user specified
visibility is local only if it is locally resolved or defined, not weak
or not compiling for PIC.  When symbol visibility is specified in the
source, we should always output symbol visibility even if symbol isn't
local to the TU.

If a global data symbol is defined in the TU, it is always local to the
executable, regardless if it is a common symbol or not.  If we aren't
compiling for shared library, locally defined global data symbol binds
locally.

gcc/

	PR rtl-optimization/32219
	* cgraphunit.c (varpool_node::finalize_decl): Set definition
	first before calling notice_global_symbol so that it is
	available to notice_global_symbol.
	* varasm.c (default_binds_local_p_1): Resolve defined data
	symbol locally if not building shared library.  Resolve symbol
	with user specified visibility locally only if it is locally
	resolved or defined, not weak or not compiling for PIC.
	(default_elf_asm_output_external): Always output visibility
	specified in the source.
	* config/darwin-protos.h (darwin_output_external): New.
	* config/darwin.c (darwin_output_external): Likewise.
	* config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.

gcc/testsuite/

	PR rtl-optimization/32219
	* gcc.dg/visibility-22.c: New test.
	* gcc.dg/visibility-23.c: Likewise.
	* gcc.target/i386/pr32219-1.c: Likewise.
	* gcc.target/i386/pr32219-2.c: Likewise.
	* gcc.target/i386/pr32219-3.c: Likewise.
	* gcc.target/i386/pr32219-4.c: Likewise.
	* gcc.target/i386/pr32219-5.c: Likewise.
	* gcc.target/i386/pr32219-6.c: Likewise.
	* gcc.target/i386/pr32219-7.c: Likewise.
	* gcc.target/i386/pr32219-8.c: Likewise.
	* gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
	of GOT relocation.
---
 gcc/cgraphunit.c                          |  4 +++-
 gcc/config/darwin-protos.h                |  1 +
 gcc/config/darwin.c                       | 15 +++++++++++++
 gcc/config/darwin.h                       |  9 ++++++++
 gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              | 35 ++++++++++++++++++-------------
 16 files changed, 217 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

Comments

Jack Howarth Feb. 7, 2015, 3:11 p.m. UTC | #1
H.J,,
    Unfortunately, the answer is yes. This patch still introduces
regressions in the g++ test suite.l These are all some form of...

Executing on host:
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
 -fno-diagnostics-show-caret -fdiagnostics-color=never  -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0  -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -multiply_defined suppress -lm   -m32  -o ./empty7.exe    (timeout =
300)
spawn -ignore SIGHUP
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0 -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-multiply_defined suppress -lm -m32 -o ./empty7.exe^M
ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
output is:
ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M


FAIL: g++.dg/abi/empty7.C  -std=gnu++98 (test for excess errors)

Darwin has really twitchy support weak symbol support so any major
rewrite will definitely be stage 1 material and likely require us to
contact the darwin linker developer at Apple for a consultation on the
meaning of these linker warnings.
            Jack



On Sat, Feb 7, 2015 at 7:27 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
>> H.J.,
>>      The new patch bootstraps okay on x86_64-apple-darwin14 but I
>
> Does it cause any regressions on x86_64-apple-darwin14?
>
>> discovered that you need a small adjustment in the deja-gnu
>> statements...
>>
>>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> 2015-02-06 21:45:04.000000000 -0500
>> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> 2015-02-07 03:24:42.000000000 -0500
>> @@ -8,9 +8,9 @@
>>  /* For kernel modules and static RTPs, the loader treats undefined weak
>>     symbols in the same way as undefined strong symbols.  The test
>>     therefore fails to load, so skip it.  */
>> +/* { dg-options "-fPIC" { target fpic } } */
>>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
>> *-*-darwin* } } */
>>  /* { dg-additional-options "-Wl,-flat_namespace" { target
>> *-*-darwin[89]* } } */
>> -/* { dg-options "-fPIC" { target fpic } } */
>>
>>  extern void foo () __attribute__((weak,visibility("hidden")));
>>  int
>>
>> If you don't define a dg-options line first, the dg-additional-options
>> lines have no effect.
>>                  Jack
>
> Here is the updated patch.
>
> H.J.
> ---
> From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 5 Feb 2015 14:28:58 -0800
> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>
> If a hidden weak symbol isn't defined in the TU, we can't assume it will
> be defined in another TU at link time.  It makes a difference in code
> generation when compiling for PIC. If we assume that a hidden weak
> undefined symbol is local, the address checking may be optimized out and
> leads to the wrong code.  This means that a symbol with user specified
> visibility is local only if it is locally resolved or defined, not weak
> or not compiling for PIC.  When symbol visibility is specified in the
> source, we should always output symbol visibility even if symbol isn't
> local to the TU.
>
> If a global data symbol is defined in the TU, it is always local to the
> executable, regardless if it is a common symbol or not.  If we aren't
> compiling for shared library, locally defined global data symbol binds
> locally.
>
> gcc/
>
>         PR rtl-optimization/32219
>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>         first before calling notice_global_symbol so that it is
>         available to notice_global_symbol.
>         * varasm.c (default_binds_local_p_1): Resolve defined data
>         symbol locally if not building shared library.  Resolve symbol
>         with user specified visibility locally only if it is locally
>         resolved or defined, not weak or not compiling for PIC.
>         (default_elf_asm_output_external): Always output visibility
>         specified in the source.
>         * config/darwin-protos.h (darwin_output_external): New.
>         * config/darwin.c (darwin_output_external): Likewise.
>         * config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.
>
> gcc/testsuite/
>
>         PR rtl-optimization/32219
>         * gcc.dg/visibility-22.c: New test.
>         * gcc.dg/visibility-23.c: Likewise.
>         * gcc.target/i386/pr32219-1.c: Likewise.
>         * gcc.target/i386/pr32219-2.c: Likewise.
>         * gcc.target/i386/pr32219-3.c: Likewise.
>         * gcc.target/i386/pr32219-4.c: Likewise.
>         * gcc.target/i386/pr32219-5.c: Likewise.
>         * gcc.target/i386/pr32219-6.c: Likewise.
>         * gcc.target/i386/pr32219-7.c: Likewise.
>         * gcc.target/i386/pr32219-8.c: Likewise.
>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>         of GOT relocation.
> ---
>  gcc/cgraphunit.c                          |  4 +++-
>  gcc/config/darwin-protos.h                |  1 +
>  gcc/config/darwin.c                       | 15 +++++++++++++
>  gcc/config/darwin.h                       |  9 ++++++++
>  gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
>  gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>  gcc/varasm.c                              | 35 ++++++++++++++++++-------------
>  16 files changed, 217 insertions(+), 17 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 35b244e..71367a3 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>
>    if (node->definition)
>      return;
> -  notice_global_symbol (decl);
> +  /* Set definition first before calling notice_global_symbol so that
> +     it is available to notice_global_symbol.  */
>    node->definition = true;
> +  notice_global_symbol (decl);
>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>        /* Traditionally we do not eliminate static variables when not
>          optimizing and when not doing toplevel reoder.  */
> diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
> index 249b9c1..10a77fc 100644
> --- a/gcc/config/darwin-protos.h
> +++ b/gcc/config/darwin-protos.h
> @@ -89,6 +89,7 @@ extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
>  extern void machopic_output_stub (FILE *, const char *, const char *);
>  extern void darwin_globalize_label (FILE *, const char *);
>  extern void darwin_assemble_visibility (tree, int);
> +extern void darwin_output_external (FILE *, tree, const char *name);
>
>  extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
>                                            const char *);
> diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
> index 40804b8..5025ef7 100644
> --- a/gcc/config/darwin.c
> +++ b/gcc/config/darwin.c
> @@ -2762,6 +2762,21 @@ darwin_assemble_visibility (tree decl, int vis)
>              "not supported in this configuration; ignored");
>  }
>
> +/* Emit text to declare externally defined symbols.  Used to support
> +   undefined hidden visibility with Darwin's private extern feature.  */
> +
> +void
> +darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
> +                       const char *name ATTRIBUTE_UNUSED)
> +{
> +  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
> +     visibility is specified in the source in order to avoid putting out
> +     names that are never really used.  */
> +  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> +      && DECL_VISIBILITY_SPECIFIED (decl))
> +    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
> +}
> +
>  /* vec used by darwin_asm_dwarf_section.
>     Maybe a hash tab would be better here - but the intention is that this is
>     a very short list (fewer than 16 items) and each entry should (ideally,
> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
> index b61dbb5..c9a1b34 100644
> --- a/gcc/config/darwin.h
> +++ b/gcc/config/darwin.h
> @@ -700,6 +700,15 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
>  #undef TARGET_ASM_ASSEMBLE_VISIBILITY
>  #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
>
> +/* A C statement (sans semicolon) to output to the stdio stream STREAM
> +   any text necessary for declaring the name of an external symbol
> +   named NAME which is referenced in this compilation but not defined.
> +   Used to support undefined hidden visibility with Darwin's private
> +   extern feature.  */
> +
> +#undef ASM_OUTPUT_EXTERNAL
> +#define ASM_OUTPUT_EXTERNAL darwin_output_external
> +
>  /* Extra attributes for Darwin.  */
>  #define SUBTARGET_ATTRIBUTE_TABLE                                           \
>    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
> new file mode 100644
> index 0000000..a118a6e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
> @@ -0,0 +1,22 @@
> +/* PR target/32219 */
> +/* { dg-do run } */
> +/* { dg-require-visibility "" } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* This test requires support for undefined weak symbols.  This support
> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
> +   xfailed to suppress the warning that would otherwise arise.  */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
> +/* For kernel modules and static RTPs, the loader treats undefined weak
> +   symbols in the same way as undefined strong symbols.  The test
> +   therefore fails to load, so skip it.  */
> +/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
> +/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
> new file mode 100644
> index 0000000..347578e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
> @@ -0,0 +1,14 @@
> +/* PR target/32219 */
> +/* { dg-do compile } */
> +/* { dg-require-visibility "" } */
> +/* { dg-final { scan-hidden "foo" } } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> new file mode 100644
> index 0000000..5bd80a0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Common symbol with -fpie.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> new file mode 100644
> index 0000000..0cf2eb5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Common symbol with -fpic.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> new file mode 100644
> index 0000000..911f2a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak common symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> new file mode 100644
> index 0000000..3d43439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak common symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> new file mode 100644
> index 0000000..ee7442e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Initialized symbol with -fpie.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> new file mode 100644
> index 0000000..f261433
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Initialized symbol with -fpic.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> new file mode 100644
> index 0000000..12aaf72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak initialized symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> new file mode 100644
> index 0000000..2e4fba0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak initialized symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
> index 33f5b5d..32969fc 100644
> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>  /* { dg-options "-O2 -fpie" } */
>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>  long c;
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index eb65b1f..f7c13af 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>      {
>        varpool_node *vnode = varpool_node::get (exp);
> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
> -       resolved_locally = true;
> -      if (vnode
> -         && resolution_to_local_definition_p (vnode->resolution))
> -       resolved_to_local_def = true;
> +      /* If not building shared library, common or initialized symbols
> +        are also resolved locally, regardless they are weak or not.  */
> +      if (vnode)
> +       {
> +         if ((!shlib && vnode->definition)
> +             || vnode->in_other_partition
> +             || resolution_local_p (vnode->resolution))
> +           resolved_locally = true;
> +         if (resolution_to_local_definition_p (vnode->resolution))
> +           resolved_to_local_def = true;
> +       }
>      }
>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>      {
> @@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (! TREE_PUBLIC (exp))
>      local_p = true;
>    /* A variable is local if the user has said explicitly that it will
> -     be.  */
> +     be and it is resolved or defined locally, not compiling for PIC or
> +     not weak.  */
>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>             || resolved_to_local_def)
> +          && (resolved_locally
> +              || !flag_pic
> +              || !DECL_EXTERNAL (exp)
> +              || !DECL_WEAK (exp))
>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>      local_p = true;
>    /* Variables defined outside this object might not be local.  */
> @@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>       symbols resolved from other modules.  */
>    else if (shlib)
>      local_p = false;
> -  /* Uninitialized COMMON variable may be unified with symbols
> -     resolved from other modules.  */
> -  else if (DECL_COMMON (exp)
> -          && !resolved_locally
> -          && (DECL_INITIAL (exp) == NULL
> -              || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
> -    local_p = false;
>    /* Otherwise we're left with initialized (or non-common) global data
>       which is of necessity defined locally.  */
>    else
> @@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +         || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);
>  }
>
> --
> 2.1.0
>
Jack Howarth Feb. 7, 2015, 3:25 p.m. UTC | #2
H.J.,
     In case it clarifies things at all, the falling testcase...

% /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0 -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-multiply_defined suppress -lm -m32 -o ./empty7.exe

produces the linker warnings...

ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.

when linking the code from empty7.o generated the following assembly in empty7.s

        .section __TEXT,__textcoal_nt,coalesced,pure_instructions
        .align 1
        .globl __ZN2S21fEv
        .weak_definition __ZN2S21fEv
__ZN2S21fEv:
LFB0:
        pushl   %ebp
LCFI0:
        movl    %esp, %ebp
LCFI1:
        call    ___x86.get_pc_thunk.ax
L1$pb:
        nop
        popl    %ebp
LCFI2:
        ret
LFE0:
        .align 1
        .globl __ZN2S7C2Ev
        .weak_definition __ZN2S7C2Ev
__ZN2S7C2Ev:
LFB3:
        pushl   %ebp
LCFI3:
        movl    %esp, %ebp
LCFI4:
        call    ___x86.get_pc_thunk.ax
L2$pb:
        nop
        popl    %ebp
LCFI5:
        ret
LFE3:
        .align 1
        .globl __ZN2S1C2Ev
        .weak_definition __ZN2S1C2Ev
__ZN2S1C2Ev:
LFB6:
        pushl   %ebp
LCFI6:
        movl    %esp, %ebp
LCFI7:
        call    ___x86.get_pc_thunk.ax
L3$pb:
        nop
        popl    %ebp
LCFI8:
        ret
LFE6:
        .align 1
        .globl __ZN2S2C2Ev
        .weak_definition __ZN2S2C2Ev
__ZN2S2C2Ev:
LFB11:
        pushl   %ebp
LCFI9:
        movl    %esp, %ebp
LCFI10:
        call    ___x86.get_pc_thunk.ax
L4$pb:
        movl    8(%ebp), %edx
        leal    __ZTV2S2-L4$pb(%eax), %eax
        leal    8(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI11:
        ret
LFE11:
        .align 1
        .globl __ZN2S4C2Ev
        .weak_definition __ZN2S4C2Ev
__ZN2S4C2Ev:
LFB14:
        pushl   %ebp
LCFI12:
        movl    %esp, %ebp
LCFI13:
        call    ___x86.get_pc_thunk.ax
L5$pb:
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        subl    $12, %eax
        movl    (%eax), %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        movl    12(%ebp), %eax
        movl    4(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI14:
        ret
LFE14:
        .align 1
        .globl __ZN2S3C2Ev
        .weak_definition __ZN2S3C2Ev
__ZN2S3C2Ev:
LFB17:
        pushl   %ebp
LCFI15:
        movl    %esp, %ebp
LCFI16:
        call    ___x86.get_pc_thunk.ax
L6$pb:
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        subl    $12, %eax
        movl    (%eax), %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        movl    12(%ebp), %eax
        movl    4(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI17:
        ret
LFE17:
        .align 1
        .globl __ZN2S5C1Ev
        .weak_definition __ZN2S5C1Ev
__ZN2S5C1Ev:
LFB20:
        pushl   %ebp
LCFI18:
        movl    %esp, %ebp
LCFI19:
        pushl   %ebx
        subl    $4, %esp
LCFI20:
        call    ___x86.get_pc_thunk.bx
L7$pb:
        movl    8(%ebp), %eax
        addl    $4, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S2C2Ev
        addl    $16, %esp
        leal    __ZTT2S5-L7$pb(%ebx), %eax
        leal    20(%eax), %eax
        movl    8(%ebp), %edx
        addl    $12, %edx
        subl    $8, %esp
        pushl   %eax
        pushl   %edx
        call    __ZN2S4C2Ev
        addl    $16, %esp
        leal    __ZTT2S5-L7$pb(%ebx), %eax
        leal    4(%eax), %eax
        movl    8(%ebp), %edx
        subl    $8, %esp
        pushl   %eax
        pushl   %edx
        call    __ZN2S3C2Ev
        addl    $16, %esp
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    16(%eax), %eax
        movl    8(%ebp), %edx
        movl    %eax, (%edx)
        movl    $4, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    28(%eax), %eax
        movl    %eax, (%edx)
        movl    $12, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    44(%eax), %eax
        movl    %eax, (%edx)
        nop
        movl    -4(%ebp), %ebx
        leave
LCFI21:
        ret
LFE20:
        .align 1
        .globl __ZN2S6C2Ev
        .weak_definition __ZN2S6C2Ev
__ZN2S6C2Ev:
LFB21:
        pushl   %ebp
LCFI22:
        movl    %esp, %ebp
LCFI23:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L8$pb:
        movl    8(%ebp), %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S5C1Ev
        addl    $16, %esp
        nop
        leave
LCFI24:
        ret
LFE21:
        .align 1
        .globl __ZN2S8C1Ev
        .weak_definition __ZN2S8C1Ev
__ZN2S8C1Ev:
LFB24:
        pushl   %ebp
LCFI25:
        movl    %esp, %ebp
LCFI26:
        pushl   %ebx
        subl    $4, %esp
LCFI27:
        call    ___x86.get_pc_thunk.bx
L9$pb:
        movl    8(%ebp), %eax
        addl    $24, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S7C2Ev
        addl    $16, %esp
        subl    $12, %esp
        pushl   8(%ebp)
        call    __ZN2S1C2Ev
        addl    $16, %esp
        movl    8(%ebp), %eax
        addl    $4, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S6C2Ev
        addl    $16, %esp
        leal    __ZTV2S8-L9$pb(%ebx), %eax
        leal    12(%eax), %eax
        movl    8(%ebp), %edx
        movl    %eax, (%edx)
        nop
        movl    -4(%ebp), %ebx
        leave
LCFI28:
        ret
LFE24:
        .globl _s8
        .zerofill __DATA,__pu_bss5,_s8,32,5
        .text
        .globl _main
_main:
LFB25:
        pushl   %ebp
LCFI29:
        movl    %esp, %ebp
LCFI30:
        call    ___x86.get_pc_thunk.ax
L10$pb:
        movl    $0, %eax
        popl    %ebp
LCFI31:
        ret
LFE25:
        .globl __ZTV2S8
        .weak_definition __ZTV2S8
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTV2S8:
        .long   24
        .long   0
        .long   __ZTI2S8
        .globl __ZTT2S8
        .weak_definition __ZTT2S8
        .align 2
__ZTT2S8:
        .long   __ZTV2S8+12
        .globl __ZTV2S5
        .weak_definition __ZTV2S5
        .align 2
__ZTV2S5:
        .long   12
        .long   4
        .long   0
        .long   __ZTI2S5
        .long   0
        .long   -4
        .long   __ZTI2S5
        .long   __ZN2S21fEv
        .long   -8
        .long   -12
        .long   __ZTI2S5
        .globl __ZTT2S5
        .weak_definition __ZTT2S5
        .align 2
__ZTT2S5:
        .long   __ZTV2S5+16
        .long   __ZTC2S50_2S3+12
        .long   __ZTC2S50_2S3+24
        .long   __ZTV2S5+28
        .long   __ZTV2S5+44
        .long   __ZTC2S512_2S4+12
        .long   __ZTC2S512_2S4+24
        .private_extern __ZTC2S50_2S3
        .globl __ZTC2S50_2S3
        .weak_definition __ZTC2S50_2S3
        .align 2
__ZTC2S50_2S3:
        .long   4
        .long   0
        .long   __ZTI2S3
        .long   0
        .long   -4
        .long   __ZTI2S3
        .long   __ZN2S21fEv
        .private_extern __ZTC2S512_2S4
        .globl __ZTC2S512_2S4
        .weak_definition __ZTC2S512_2S4
        .align 2
__ZTC2S512_2S4:
        .long   -8
        .long   0
        .long   __ZTI2S4
        .long   0
        .long   8
        .long   __ZTI2S4
        .long   __ZN2S21fEv
        .globl __ZTV2S2
        .weak_definition __ZTV2S2
        .align 2
__ZTV2S2:
        .long   0
        .long   __ZTI2S2
        .long   __ZN2S21fEv
        .globl __ZTI2S8
        .weak_definition __ZTI2S8
        .align 2
__ZTI2S8:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S8
        .long   0
        .long   3
        .long   __ZTI2S1
        .long   2
        .long   __ZTI2S6
        .long   1026
        .long   __ZTI2S7
        .long   -3069
        .globl __ZTS2S8
        .weak_definition __ZTS2S8
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S8:
        .ascii "2S8\0"
        .globl __ZTI2S5
        .weak_definition __ZTI2S5
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S5:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S5
        .long   2
        .long   2
        .long   __ZTI2S3
        .long   2
        .long   __ZTI2S4
        .long   -4093
        .globl __ZTS2S5
        .weak_definition __ZTS2S5
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S5:
        .ascii "2S5\0"
        .globl __ZTI2S4
        .weak_definition __ZTI2S4
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S4:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S4
        .long   0
        .long   1
        .long   __ZTI2S2
        .long   -3069
        .globl __ZTS2S4
        .weak_definition __ZTS2S4
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S4:
        .ascii "2S4\0"
        .globl __ZTI2S3
        .weak_definition __ZTI2S3
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S3:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S3
        .long   0
        .long   1
        .long   __ZTI2S2
        .long   -3069
        .globl __ZTS2S3
        .weak_definition __ZTS2S3
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S3:
        .ascii "2S3\0"
        .globl __ZTI2S2
        .weak_definition __ZTI2S2
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S2:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S2
        .globl __ZTS2S2
        .weak_definition __ZTS2S2
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S2:
        .ascii "2S2\0"
        .text
__Z41__static_initialization_and_destruction_0ii:
LFB26:
        pushl   %ebp
LCFI32:
        movl    %esp, %ebp
LCFI33:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L11$pb:
        cmpl    $1, 8(%ebp)
        jne     L14
        cmpl    $65535, 12(%ebp)
        jne     L14
        subl    $12, %esp
        leal    _s8-L11$pb(%eax), %eax
        pushl   %eax
        call    __ZN2S8C1Ev
        addl    $16, %esp
L14:
        nop
        leave
LCFI34:
        ret
LFE26:
        .globl __ZTI2S7
        .weak_definition __ZTI2S7
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S7:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S7
        .globl __ZTS2S7
        .weak_definition __ZTS2S7
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S7:
        .ascii "2S7\0"
        .globl __ZTI2S1
        .weak_definition __ZTI2S1
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S1:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S1
        .globl __ZTS2S1
        .weak_definition __ZTS2S1
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S1:
        .ascii "2S1\0"
        .globl __ZTI2S6
        .weak_definition __ZTI2S6
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S6:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S6
        .globl __ZTS2S6
        .weak_definition __ZTS2S6
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S6:
        .ascii "2S6\0"
        .text
__GLOBAL__sub_I_empty7.C:
LFB27:
        pushl   %ebp
LCFI35:
        movl    %esp, %ebp
LCFI36:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L12$pb:
        subl    $8, %esp
        pushl   $65535
        pushl   $1
        call    __Z41__static_initialization_and_destruction_0ii
        addl    $16, %esp
        leave
LCFI37:
        ret
LFE27:
        .section __TEXT,__textcoal_nt,coalesced,pure_instructions
        .weak_definition        ___x86.get_pc_thunk.ax
        .private_extern ___x86.get_pc_thunk.ax
___x86.get_pc_thunk.ax:
LFB28:
        movl    (%esp), %eax
        ret
LFE28:
        .weak_definition        ___x86.get_pc_thunk.bx
        .private_extern ___x86.get_pc_thunk.bx
___x86.get_pc_thunk.bx:
LFB29:
        movl    (%esp), %ebx
        ret
LFE29:
        .section
__TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
        .set L$set$0,LECIE1-LSCIE1
        .long L$set$0
LSCIE1:
        .long   0
        .byte   0x1
        .ascii "zR\0"
        .byte   0x1
        .byte   0x7c
        .byte   0x8
        .byte   0x1
        .byte   0x10
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .byte   0x88
        .byte   0x1
        .align 2
LECIE1:
LSFDE1:
        .set L$set$1,LEFDE1-LASFDE1
        .long L$set$1
LASFDE1:
        .long   LASFDE1-EH_frame1
        .long   LFB0-.
        .set L$set$2,LFE0-LFB0
        .long L$set$2
        .byte   0
        .byte   0x4
        .set L$set$3,LCFI0-LFB0
        .long L$set$3
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$4,LCFI1-LCFI0
        .long L$set$4
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$5,LCFI2-LCFI1
        .long L$set$5
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE1:
LSFDE3:
        .set L$set$6,LEFDE3-LASFDE3
        .long L$set$6
LASFDE3:
        .long   LASFDE3-EH_frame1
        .long   LFB3-.
        .set L$set$7,LFE3-LFB3
        .long L$set$7
        .byte   0
        .byte   0x4
        .set L$set$8,LCFI3-LFB3
        .long L$set$8
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$9,LCFI4-LCFI3
        .long L$set$9
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$10,LCFI5-LCFI4
        .long L$set$10
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE3:
LSFDE5:
        .set L$set$11,LEFDE5-LASFDE5
        .long L$set$11
LASFDE5:
        .long   LASFDE5-EH_frame1
        .long   LFB6-.
        .set L$set$12,LFE6-LFB6
        .long L$set$12
        .byte   0
        .byte   0x4
        .set L$set$13,LCFI6-LFB6
        .long L$set$13
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$14,LCFI7-LCFI6
        .long L$set$14
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$15,LCFI8-LCFI7
        .long L$set$15
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE5:
LSFDE7:
        .set L$set$16,LEFDE7-LASFDE7
        .long L$set$16
LASFDE7:
        .long   LASFDE7-EH_frame1
        .long   LFB11-.
        .set L$set$17,LFE11-LFB11
        .long L$set$17
        .byte   0
        .byte   0x4
        .set L$set$18,LCFI9-LFB11
        .long L$set$18
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$19,LCFI10-LCFI9
        .long L$set$19
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$20,LCFI11-LCFI10
        .long L$set$20
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE7:
LSFDE9:
        .set L$set$21,LEFDE9-LASFDE9
        .long L$set$21
LASFDE9:
        .long   LASFDE9-EH_frame1
        .long   LFB14-.
        .set L$set$22,LFE14-LFB14
        .long L$set$22
        .byte   0
        .byte   0x4
        .set L$set$23,LCFI12-LFB14
        .long L$set$23
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$24,LCFI13-LCFI12
        .long L$set$24
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$25,LCFI14-LCFI13
        .long L$set$25
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE9:
LSFDE11:
        .set L$set$26,LEFDE11-LASFDE11
        .long L$set$26
LASFDE11:
        .long   LASFDE11-EH_frame1
        .long   LFB17-.
        .set L$set$27,LFE17-LFB17
        .long L$set$27
        .byte   0
        .byte   0x4
        .set L$set$28,LCFI15-LFB17
        .long L$set$28
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$29,LCFI16-LCFI15
        .long L$set$29
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$30,LCFI17-LCFI16
        .long L$set$30
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE11:
LSFDE13:
        .set L$set$31,LEFDE13-LASFDE13
        .long L$set$31
LASFDE13:
        .long   LASFDE13-EH_frame1
        .long   LFB20-.
        .set L$set$32,LFE20-LFB20
        .long L$set$32
        .byte   0
        .byte   0x4
        .set L$set$33,LCFI18-LFB20
        .long L$set$33
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$34,LCFI19-LCFI18
        .long L$set$34
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$35,LCFI20-LCFI19
        .long L$set$35
        .byte   0x83
        .byte   0x3
        .byte   0x4
        .set L$set$36,LCFI21-LCFI20
        .long L$set$36
        .byte   0xc4
        .byte   0xc3
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE13:
LSFDE15:
        .set L$set$37,LEFDE15-LASFDE15
        .long L$set$37
LASFDE15:
        .long   LASFDE15-EH_frame1
        .long   LFB21-.
        .set L$set$38,LFE21-LFB21
        .long L$set$38
        .byte   0
        .byte   0x4
        .set L$set$39,LCFI22-LFB21
        .long L$set$39
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$40,LCFI23-LCFI22
        .long L$set$40
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$41,LCFI24-LCFI23
        .long L$set$41
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE15:
LSFDE17:
        .set L$set$42,LEFDE17-LASFDE17
        .long L$set$42
LASFDE17:
        .long   LASFDE17-EH_frame1
        .long   LFB24-.
        .set L$set$43,LFE24-LFB24
        .long L$set$43
        .byte   0
        .byte   0x4
        .set L$set$44,LCFI25-LFB24
        .long L$set$44
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$45,LCFI26-LCFI25
        .long L$set$45
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$46,LCFI27-LCFI26
        .long L$set$46
        .byte   0x83
        .byte   0x3
        .byte   0x4
        .set L$set$47,LCFI28-LCFI27
        .long L$set$47
        .byte   0xc4
        .byte   0xc3
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE17:
LSFDE19:
        .set L$set$48,LEFDE19-LASFDE19
        .long L$set$48
LASFDE19:
        .long   LASFDE19-EH_frame1
        .long   LFB25-.
        .set L$set$49,LFE25-LFB25
        .long L$set$49
        .byte   0
        .byte   0x4
        .set L$set$50,LCFI29-LFB25
        .long L$set$50
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$51,LCFI30-LCFI29
        .long L$set$51
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$52,LCFI31-LCFI30
        .long L$set$52
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE19:
LSFDE21:
        .set L$set$53,LEFDE21-LASFDE21
        .long L$set$53
LASFDE21:
        .long   LASFDE21-EH_frame1
        .long   LFB26-.
        .set L$set$54,LFE26-LFB26
        .long L$set$54
        .byte   0
        .byte   0x4
        .set L$set$55,LCFI32-LFB26
        .long L$set$55
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$56,LCFI33-LCFI32
        .long L$set$56
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$57,LCFI34-LCFI33
        .long L$set$57
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE21:
LSFDE23:
        .set L$set$58,LEFDE23-LASFDE23
        .long L$set$58
LASFDE23:
        .long   LASFDE23-EH_frame1
        .long   LFB27-.
        .set L$set$59,LFE27-LFB27
        .long L$set$59
        .byte   0
        .byte   0x4
        .set L$set$60,LCFI35-LFB27
        .long L$set$60
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$61,LCFI36-LCFI35
        .long L$set$61
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$62,LCFI37-LCFI36
        .long L$set$62
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE23:
LSFDE25:
        .set L$set$63,LEFDE25-LASFDE25
        .long L$set$63
LASFDE25:
        .long   LASFDE25-EH_frame1
        .long   LFB28-.
        .set L$set$64,LFE28-LFB28
        .long L$set$64
        .byte   0
        .align 2
LEFDE25:
LSFDE27:
        .set L$set$65,LEFDE27-LASFDE27
        .long L$set$65
LASFDE27:
        .long   LASFDE27-EH_frame1
        .long   LFB29-.
        .set L$set$66,LFE29-LFB29
        .long L$set$66
        .byte   0
        .align 2
LEFDE27:
        .mod_init_func
        .align 2
        .long   __GLOBAL__sub_I_empty7.C
        .constructor
        .destructor
        .align 1
        .subsections_via_symbols



On Sat, Feb 7, 2015 at 10:11 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J,,
>     Unfortunately, the answer is yes. This patch still introduces
> regressions in the g++ test suite.l These are all some form of...
>
> Executing on host:
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
>  -fno-diagnostics-show-caret -fdiagnostics-color=never  -nostdinc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
> -fmessage-length=0  -std=gnu++98 -fabi-version=0
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -multiply_defined suppress -lm   -m32  -o ./empty7.exe    (timeout =
> 300)
> spawn -ignore SIGHUP
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
> -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
> -fmessage-length=0 -std=gnu++98 -fabi-version=0
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -multiply_defined suppress -lm -m32 -o ./empty7.exe^M
> ld: warning: direct access in S2::S2()    to global weak symbol vtable
> for S2 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S8::S8()    to global weak symbol vtable
> for S8 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> output is:
> ld: warning: direct access in S2::S2()    to global weak symbol vtable
> for S2 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S8::S8()    to global weak symbol vtable
> for S8 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
>
>
> FAIL: g++.dg/abi/empty7.C  -std=gnu++98 (test for excess errors)
>
> Darwin has really twitchy support weak symbol support so any major
> rewrite will definitely be stage 1 material and likely require us to
> contact the darwin linker developer at Apple for a consultation on the
> meaning of these linker warnings.
>             Jack
>
>
>
> On Sat, Feb 7, 2015 at 7:27 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
>>> H.J.,
>>>      The new patch bootstraps okay on x86_64-apple-darwin14 but I
>>
>> Does it cause any regressions on x86_64-apple-darwin14?
>>
>>> discovered that you need a small adjustment in the deja-gnu
>>> statements...
>>>
>>>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>> 2015-02-06 21:45:04.000000000 -0500
>>> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>> 2015-02-07 03:24:42.000000000 -0500
>>> @@ -8,9 +8,9 @@
>>>  /* For kernel modules and static RTPs, the loader treats undefined weak
>>>     symbols in the same way as undefined strong symbols.  The test
>>>     therefore fails to load, so skip it.  */
>>> +/* { dg-options "-fPIC" { target fpic } } */
>>>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
>>> *-*-darwin* } } */
>>>  /* { dg-additional-options "-Wl,-flat_namespace" { target
>>> *-*-darwin[89]* } } */
>>> -/* { dg-options "-fPIC" { target fpic } } */
>>>
>>>  extern void foo () __attribute__((weak,visibility("hidden")));
>>>  int
>>>
>>> If you don't define a dg-options line first, the dg-additional-options
>>> lines have no effect.
>>>                  Jack
>>
>> Here is the updated patch.
>>
>> H.J.
>> ---
>> From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>> Date: Thu, 5 Feb 2015 14:28:58 -0800
>> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>>
>> If a hidden weak symbol isn't defined in the TU, we can't assume it will
>> be defined in another TU at link time.  It makes a difference in code
>> generation when compiling for PIC. If we assume that a hidden weak
>> undefined symbol is local, the address checking may be optimized out and
>> leads to the wrong code.  This means that a symbol with user specified
>> visibility is local only if it is locally resolved or defined, not weak
>> or not compiling for PIC.  When symbol visibility is specified in the
>> source, we should always output symbol visibility even if symbol isn't
>> local to the TU.
>>
>> If a global data symbol is defined in the TU, it is always local to the
>> executable, regardless if it is a common symbol or not.  If we aren't
>> compiling for shared library, locally defined global data symbol binds
>> locally.
>>
>> gcc/
>>
>>         PR rtl-optimization/32219
>>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>>         first before calling notice_global_symbol so that it is
>>         available to notice_global_symbol.
>>         * varasm.c (default_binds_local_p_1): Resolve defined data
>>         symbol locally if not building shared library.  Resolve symbol
>>         with user specified visibility locally only if it is locally
>>         resolved or defined, not weak or not compiling for PIC.
>>         (default_elf_asm_output_external): Always output visibility
>>         specified in the source.
>>         * config/darwin-protos.h (darwin_output_external): New.
>>         * config/darwin.c (darwin_output_external): Likewise.
>>         * config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.
>>
>> gcc/testsuite/
>>
>>         PR rtl-optimization/32219
>>         * gcc.dg/visibility-22.c: New test.
>>         * gcc.dg/visibility-23.c: Likewise.
>>         * gcc.target/i386/pr32219-1.c: Likewise.
>>         * gcc.target/i386/pr32219-2.c: Likewise.
>>         * gcc.target/i386/pr32219-3.c: Likewise.
>>         * gcc.target/i386/pr32219-4.c: Likewise.
>>         * gcc.target/i386/pr32219-5.c: Likewise.
>>         * gcc.target/i386/pr32219-6.c: Likewise.
>>         * gcc.target/i386/pr32219-7.c: Likewise.
>>         * gcc.target/i386/pr32219-8.c: Likewise.
>>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>>         of GOT relocation.
>> ---
>>  gcc/cgraphunit.c                          |  4 +++-
>>  gcc/config/darwin-protos.h                |  1 +
>>  gcc/config/darwin.c                       | 15 +++++++++++++
>>  gcc/config/darwin.h                       |  9 ++++++++
>>  gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
>>  gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>>  gcc/varasm.c                              | 35 ++++++++++++++++++-------------
>>  16 files changed, 217 insertions(+), 17 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>>
>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>> index 35b244e..71367a3 100644
>> --- a/gcc/cgraphunit.c
>> +++ b/gcc/cgraphunit.c
>> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>>
>>    if (node->definition)
>>      return;
>> -  notice_global_symbol (decl);
>> +  /* Set definition first before calling notice_global_symbol so that
>> +     it is available to notice_global_symbol.  */
>>    node->definition = true;
>> +  notice_global_symbol (decl);
>>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>>        /* Traditionally we do not eliminate static variables when not
>>          optimizing and when not doing toplevel reoder.  */
>> diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
>> index 249b9c1..10a77fc 100644
>> --- a/gcc/config/darwin-protos.h
>> +++ b/gcc/config/darwin-protos.h
>> @@ -89,6 +89,7 @@ extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
>>  extern void machopic_output_stub (FILE *, const char *, const char *);
>>  extern void darwin_globalize_label (FILE *, const char *);
>>  extern void darwin_assemble_visibility (tree, int);
>> +extern void darwin_output_external (FILE *, tree, const char *name);
>>
>>  extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
>>                                            const char *);
>> diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
>> index 40804b8..5025ef7 100644
>> --- a/gcc/config/darwin.c
>> +++ b/gcc/config/darwin.c
>> @@ -2762,6 +2762,21 @@ darwin_assemble_visibility (tree decl, int vis)
>>              "not supported in this configuration; ignored");
>>  }
>>
>> +/* Emit text to declare externally defined symbols.  Used to support
>> +   undefined hidden visibility with Darwin's private extern feature.  */
>> +
>> +void
>> +darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
>> +                       const char *name ATTRIBUTE_UNUSED)
>> +{
>> +  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
>> +     visibility is specified in the source in order to avoid putting out
>> +     names that are never really used.  */
>> +  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> +      && DECL_VISIBILITY_SPECIFIED (decl))
>> +    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
>> +}
>> +
>>  /* vec used by darwin_asm_dwarf_section.
>>     Maybe a hash tab would be better here - but the intention is that this is
>>     a very short list (fewer than 16 items) and each entry should (ideally,
>> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
>> index b61dbb5..c9a1b34 100644
>> --- a/gcc/config/darwin.h
>> +++ b/gcc/config/darwin.h
>> @@ -700,6 +700,15 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
>>  #undef TARGET_ASM_ASSEMBLE_VISIBILITY
>>  #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
>>
>> +/* A C statement (sans semicolon) to output to the stdio stream STREAM
>> +   any text necessary for declaring the name of an external symbol
>> +   named NAME which is referenced in this compilation but not defined.
>> +   Used to support undefined hidden visibility with Darwin's private
>> +   extern feature.  */
>> +
>> +#undef ASM_OUTPUT_EXTERNAL
>> +#define ASM_OUTPUT_EXTERNAL darwin_output_external
>> +
>>  /* Extra attributes for Darwin.  */
>>  #define SUBTARGET_ATTRIBUTE_TABLE                                           \
>>    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
>> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
>> new file mode 100644
>> index 0000000..a118a6e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
>> @@ -0,0 +1,22 @@
>> +/* PR target/32219 */
>> +/* { dg-do run } */
>> +/* { dg-require-visibility "" } */
>> +/* { dg-options "-O2 -fPIC" { target fpic } } */
>> +/* This test requires support for undefined weak symbols.  This support
>> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
>> +   xfailed to suppress the warning that would otherwise arise.  */
>> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
>> +/* For kernel modules and static RTPs, the loader treats undefined weak
>> +   symbols in the same way as undefined strong symbols.  The test
>> +   therefore fails to load, so skip it.  */
>> +/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
>> +/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
>> +
>> +extern void foo () __attribute__((weak,visibility("hidden")));
>> +int
>> +main()
>> +{
>> +  if (foo)
>> +    foo ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
>> new file mode 100644
>> index 0000000..347578e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
>> @@ -0,0 +1,14 @@
>> +/* PR target/32219 */
>> +/* { dg-do compile } */
>> +/* { dg-require-visibility "" } */
>> +/* { dg-final { scan-hidden "foo" } } */
>> +/* { dg-options "-O2 -fPIC" { target fpic } } */
>> +
>> +extern void foo () __attribute__((weak,visibility("hidden")));
>> +int
>> +main()
>> +{
>> +  if (foo)
>> +    foo ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
>> new file mode 100644
>> index 0000000..5bd80a0
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Common symbol with -fpie.  */
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
>> new file mode 100644
>> index 0000000..0cf2eb5
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Common symbol with -fpic.  */
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
>> new file mode 100644
>> index 0000000..911f2a5
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Weak common symbol with -fpie.  */
>> +__attribute__((weak))
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
>> new file mode 100644
>> index 0000000..3d43439
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Weak common symbol with -fpic.  */
>> +__attribute__((weak))
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
>> new file mode 100644
>> index 0000000..ee7442e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Initialized symbol with -fpie.  */
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
>> new file mode 100644
>> index 0000000..f261433
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Initialized symbol with -fpic.  */
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
>> new file mode 100644
>> index 0000000..12aaf72
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Weak initialized symbol with -fpie.  */
>> +__attribute__((weak))
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
>> new file mode 100644
>> index 0000000..2e4fba0
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Weak initialized symbol with -fpic.  */
>> +__attribute__((weak))
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
>> index 33f5b5d..32969fc 100644
>> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
>> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
>> @@ -1,7 +1,7 @@
>>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>>  /* { dg-options "-O2 -fpie" } */
>>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
>> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
>> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>>  long c;
>>
>> diff --git a/gcc/varasm.c b/gcc/varasm.c
>> index eb65b1f..f7c13af 100644
>> --- a/gcc/varasm.c
>> +++ b/gcc/varasm.c
>> @@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>>      {
>>        varpool_node *vnode = varpool_node::get (exp);
>> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
>> -       resolved_locally = true;
>> -      if (vnode
>> -         && resolution_to_local_definition_p (vnode->resolution))
>> -       resolved_to_local_def = true;
>> +      /* If not building shared library, common or initialized symbols
>> +        are also resolved locally, regardless they are weak or not.  */
>> +      if (vnode)
>> +       {
>> +         if ((!shlib && vnode->definition)
>> +             || vnode->in_other_partition
>> +             || resolution_local_p (vnode->resolution))
>> +           resolved_locally = true;
>> +         if (resolution_to_local_definition_p (vnode->resolution))
>> +           resolved_to_local_def = true;
>> +       }
>>      }
>>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>>      {
>> @@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>    else if (! TREE_PUBLIC (exp))
>>      local_p = true;
>>    /* A variable is local if the user has said explicitly that it will
>> -     be.  */
>> +     be and it is resolved or defined locally, not compiling for PIC or
>> +     not weak.  */
>>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>>             || resolved_to_local_def)
>> +          && (resolved_locally
>> +              || !flag_pic
>> +              || !DECL_EXTERNAL (exp)
>> +              || !DECL_WEAK (exp))
>>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>>      local_p = true;
>>    /* Variables defined outside this object might not be local.  */
>> @@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>       symbols resolved from other modules.  */
>>    else if (shlib)
>>      local_p = false;
>> -  /* Uninitialized COMMON variable may be unified with symbols
>> -     resolved from other modules.  */
>> -  else if (DECL_COMMON (exp)
>> -          && !resolved_locally
>> -          && (DECL_INITIAL (exp) == NULL
>> -              || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
>> -    local_p = false;
>>    /* Otherwise we're left with initialized (or non-common) global data
>>       which is of necessity defined locally.  */
>>    else
>> @@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>>  {
>>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>>       set in order to avoid putting out names that are never really
>> -     used. */
>> +     used.   Always output visibility specified in the source.  */
>>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> -      && targetm.binds_local_p (decl))
>> +      && (DECL_VISIBILITY_SPECIFIED (decl)
>> +         || targetm.binds_local_p (decl)))
>>      maybe_assemble_visibility (decl);
>>  }
>>
>> --
>> 2.1.0
>>
diff mbox

Patch

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 35b244e..71367a3 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -792,8 +792,10 @@  varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 249b9c1..10a77fc 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -89,6 +89,7 @@  extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
 extern void machopic_output_stub (FILE *, const char *, const char *);
 extern void darwin_globalize_label (FILE *, const char *);
 extern void darwin_assemble_visibility (tree, int);
+extern void darwin_output_external (FILE *, tree, const char *name);
 
 extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
 					   const char *);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 40804b8..5025ef7 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2762,6 +2762,21 @@  darwin_assemble_visibility (tree decl, int vis)
 	     "not supported in this configuration; ignored");
 }
 
+/* Emit text to declare externally defined symbols.  Used to support
+   undefined hidden visibility with Darwin's private extern feature.  */
+
+void
+darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
+			const char *name ATTRIBUTE_UNUSED)
+{
+  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
+     visibility is specified in the source in order to avoid putting out
+     names that are never really used.  */
+  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+      && DECL_VISIBILITY_SPECIFIED (decl))
+    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
+}
+
 /* vec used by darwin_asm_dwarf_section.
    Maybe a hash tab would be better here - but the intention is that this is
    a very short list (fewer than 16 items) and each entry should (ideally, 
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index b61dbb5..c9a1b34 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -700,6 +700,15 @@  extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
 #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
 
+/* A C statement (sans semicolon) to output to the stdio stream STREAM
+   any text necessary for declaring the name of an external symbol
+   named NAME which is referenced in this compilation but not defined.
+   Used to support undefined hidden visibility with Darwin's private
+   extern feature.  */
+
+#undef ASM_OUTPUT_EXTERNAL
+#define ASM_OUTPUT_EXTERNAL darwin_output_external
+
 /* Extra attributes for Darwin.  */
 #define SUBTARGET_ATTRIBUTE_TABLE					     \
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..a118a6e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,22 @@ 
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
+/* For kernel modules and static RTPs, the loader treats undefined weak
+   symbols in the same way as undefined strong symbols.  The test
+   therefore fails to load, so skip it.  */
+/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
+/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..347578e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,14 @@ 
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@ 
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..f7c13af 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6826,11 +6826,17 @@  default_binds_local_p_1 (const_tree exp, int shlib)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
     {
       varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
+      /* If not building shared library, common or initialized symbols
+	 are also resolved locally, regardless they are weak or not.  */
+      if (vnode)
+	{
+	  if ((!shlib && vnode->definition)
+	      || vnode->in_other_partition
+	      || resolution_local_p (vnode->resolution))
+	    resolved_locally = true;
+	  if (resolution_to_local_definition_p (vnode->resolution))
+	    resolved_to_local_def = true;
+	}
     }
   else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
     {
@@ -6859,9 +6865,14 @@  default_binds_local_p_1 (const_tree exp, int shlib)
   else if (! TREE_PUBLIC (exp))
     local_p = true;
   /* A variable is local if the user has said explicitly that it will
-     be.  */
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
   else if ((DECL_VISIBILITY_SPECIFIED (exp)
 	    || resolved_to_local_def)
+	   && (resolved_locally
+	       || !flag_pic
+	       || !DECL_EXTERNAL (exp)
+	       || !DECL_WEAK (exp))
 	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     local_p = true;
   /* Variables defined outside this object might not be local.  */
@@ -6880,13 +6891,6 @@  default_binds_local_p_1 (const_tree exp, int shlib)
      symbols resolved from other modules.  */
   else if (shlib)
     local_p = false;
-  /* Uninitialized COMMON variable may be unified with symbols
-     resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
   else
@@ -7445,9 +7449,10 @@  default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }