diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57153ed8e4b..29a37f44afb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,26 @@ 2005-12-05 Geoffrey Keating + * varasm.c (default_binds_local_p_1): Weakrefs don't bind locally. + A hidden weak object does bind locally. Strong linkonce data + counts like any other strong symbol for binding. + (weak_finish_1): Don't specially handle weakrefs, they no longer + arrive here. + (assemble_alias): Weakrefs can't be TREE_PUBLIC yet. + * c-common.c (handle_alias_attribute): Allow static aliases + of variables. + (handle_weakref_attribute): Don't call declare_weak on weakrefs. + * gthr-dce.h: Make weakrefs static. + * gthr-tpf.h: Likewise. + * gthr-solaris.h: Likewise. + * gthr-posix.h: Likewise. + * gthr-posix95.h: Likewise. + * config/darwin.c (darwin_encode_section_info): static weakref + variables are not necessarily defined in this translation unit. + * doc/extend.texi (Function Attributes): Mention that an alias + attribute creates a definition for the thing it's attached to. + Change the documentation for weakref to say that the thing + it's attached to must be static. + * config/rs6000/host-darwin.c (segv_handler): Unblock SEGV so we don't go into an infinite loop. diff --git a/gcc/c-common.c b/gcc/c-common.c index 27934dd6a0a..557cd554a8f 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4751,7 +4751,12 @@ handle_alias_attribute (tree *node, tree name, tree args, tree decl = *node; if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - || (TREE_CODE (decl) != FUNCTION_DECL && !DECL_EXTERNAL (decl))) + || (TREE_CODE (decl) != FUNCTION_DECL + && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) + /* A static variable declaration is always a tentative definition, + but the alias is a non-tentative definition which overrides. */ + || (TREE_CODE (decl) != FUNCTION_DECL + && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl))) { error ("%q+D defined both normally and as an alias", decl); *no_add_attrs = true; @@ -4816,6 +4821,8 @@ handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args, attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr); *no_add_attrs = true; + + decl_attributes (node, attr, flags); } else { @@ -4823,11 +4830,12 @@ handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args, error ("%Jweakref attribute must appear before alias attribute", *node); - attr = tree_cons (get_identifier ("weak"), NULL_TREE, attr); + /* Can't call declare_weak because it wants this to be TREE_PUBLIC, + and that isn't supported; and because it wants to add it to + the list of weak decls, which isn't helpful. */ + DECL_WEAK (*node) = 1; } - decl_attributes (node, attr, flags); - return NULL_TREE; } diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 98c7d30cd72..49c4114c2d2 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -1003,6 +1003,7 @@ darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) if (!DECL_EXTERNAL (decl) && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl)) + && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)) && ((TREE_STATIC (decl) && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl))) || (!DECL_COMMON (decl) && DECL_INITIAL (decl) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a796da62685..341d6248cde 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1554,7 +1554,7 @@ void __f () @{ /* @r{Do something.} */; @} void f () __attribute__ ((weak, alias ("__f"))); @end smallexample -declares @samp{f} to be a weak alias for @samp{__f}. In C++, the +defines @samp{f} to be a weak alias for @samp{__f}. In C++, the mangled name for the target must be used. It is an error if @samp{__f} is not defined in the same translation unit. @@ -2376,12 +2376,12 @@ implicitly marks the declaration as @code{weak}. Without a @code{weakref} is equivalent to @code{weak}. @smallexample -extern int x() __attribute__ ((weakref ("y"))); +static int x() __attribute__ ((weakref ("y"))); /* is equivalent to... */ -extern int x() __attribute__ ((weak, weakref, alias ("y"))); +static int x() __attribute__ ((weak, weakref, alias ("y"))); /* and to... */ -extern int x() __attribute__ ((weakref)); -extern int x() __attribute__ ((alias ("y"))); +static int x() __attribute__ ((weakref)); +static int x() __attribute__ ((alias ("y"))); @end smallexample A weak reference is an alias that does not by itself require a @@ -2396,6 +2396,9 @@ separate translation unit, renaming the alias to the aliased symbol, declaring it as weak, compiling the two separate translation units and performing a reloadable link on them. +At present, a declaration to which @code{weakref} is attached can +only be @code{static}. + @item externally_visible @cindex @code{externally_visible} attribute. This attribute, attached to a global variable or function nullify diff --git a/gcc/gthr-dce.h b/gcc/gthr-dce.h index 517f5a30443..fe4bba769d9 100644 --- a/gcc/gthr-dce.h +++ b/gcc/gthr-dce.h @@ -64,7 +64,7 @@ typedef pthread_mutex_t __gthread_recursive_mutex_t; #if SUPPORTS_WEAK && GTHREAD_USE_WEAK # define __gthrw(name) \ - extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) #else # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname) # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h index d022c9f1b79..e36a76d19ab 100644 --- a/gcc/gthr-posix.h +++ b/gcc/gthr-posix.h @@ -60,7 +60,7 @@ typedef pthread_mutex_t __gthread_recursive_mutex_t; #if SUPPORTS_WEAK && GTHREAD_USE_WEAK # define __gthrw(name) \ - extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) #else # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname) # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname diff --git a/gcc/gthr-posix95.h b/gcc/gthr-posix95.h index 71661eb8091..f4ee09fb028 100644 --- a/gcc/gthr-posix95.h +++ b/gcc/gthr-posix95.h @@ -58,7 +58,7 @@ typedef struct { #if SUPPORTS_WEAK && GTHREAD_USE_WEAK # define __gthrw(name) \ - extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) #else # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname) # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname diff --git a/gcc/gthr-solaris.h b/gcc/gthr-solaris.h index 01757dc006d..b0ceba6d1c4 100644 --- a/gcc/gthr-solaris.h +++ b/gcc/gthr-solaris.h @@ -58,7 +58,7 @@ typedef struct { #if SUPPORTS_WEAK && GTHREAD_USE_WEAK # define __gthrw(name) \ - extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) #else # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname) # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname diff --git a/gcc/gthr-tpf.h b/gcc/gthr-tpf.h index d54a6c80171..f797a49671f 100644 --- a/gcc/gthr-tpf.h +++ b/gcc/gthr-tpf.h @@ -70,7 +70,7 @@ typedef pthread_mutex_t __gthread_recursive_mutex_t; #if SUPPORTS_WEAK && GTHREAD_USE_WEAK # define __gthrw(name) \ - extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) + static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) #else # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname) # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05418ed35ad..1fbd36c89f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2005-12-05 Geoffrey Keating + + * g++.old-deja/g++.abi/vtable2.C: Make weakrefs static. + * gcc.dg/attr-weakref-1.c: Modify to not try to test public weakrefs, + and to work on Darwin. + * gcc.dg/attr-weakref-1b.c: New file. + * gcc.dg/attr-weakref-2.c: New test. + * gcc.dg/darwin-weakref-1.c: New test. + 2005-12-05 Janis Johnson PR testsuite/25247 diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C index a36cf0e7f17..b64f0fc257a 100644 --- a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C +++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C @@ -127,8 +127,8 @@ extern "C" { /* We can use weakref here without dg-require-weak, because we know the symbols are defined, so we don't actually issue the .weak directives. */ - void S3_s3 () __attribute__((__weakref__ ("_ZN2S32s3Ev"))); - void S4_s1 () __attribute__((__weakref__ ("_ZN2S42s1Ev"))); + static void S3_s3 () __attribute__((__weakref__ ("_ZN2S32s3Ev"))); + static void S4_s1 () __attribute__((__weakref__ ("_ZN2S42s1Ev"))); } // IA-64 uses function descriptors not function pointers in its vtables. diff --git a/gcc/testsuite/gcc.dg/attr-weakref-1.c b/gcc/testsuite/gcc.dg/attr-weakref-1.c index c47ce1e569b..7ffd64d55ca 100644 --- a/gcc/testsuite/gcc.dg/attr-weakref-1.c +++ b/gcc/testsuite/gcc.dg/attr-weakref-1.c @@ -1,7 +1,9 @@ // { dg-do run } // { dg-require-weak "" } // { dg-options "-O2" } +// { dg-options "-O2 -mmacosx-version-min=10.2" { target { powerpc-*-darwin* } } } // { dg-additional-sources "attr-weakref-1a.c" } +// { dg-additional-sources "attr-weakref-1a.c attr-weakref-1b.c" { target { *-*-darwin* } } } // Copyright 2005 Free Software Foundation, Inc. // Contributed by Alexandre Oliva @@ -26,37 +28,32 @@ typedef int vtype; extern vtype wv1; -extern vtype Wv1a __attribute__((weakref ("wv1"))); +static vtype Wv1a __attribute__((weakref ("wv1"))); static vtype *pv1a USED = &Wv1a; -extern vtype Wv1b __attribute__((weak, weakref, alias ("wv1"))); -static vtype *pv1b USED = &Wv1b; -extern vtype Wv1c __attribute__((weakref)); -extern vtype Wv1c __attribute__((alias ("wv1"))); -static vtype *pv1c USED = &Wv1c; vtype gv2; -extern vtype Wv2a __attribute__((weakref ("gv2"))); +static vtype Wv2a __attribute__((weakref ("gv2"))); static vtype *pv2a USED = &Wv2a; static vtype lv3; -extern vtype Wv3a __attribute__((weakref ("lv3"))); +static vtype Wv3a __attribute__((weakref ("lv3"))); static vtype *pv3a USED = &Wv3a; extern vtype uv4; -extern vtype Wv4a __attribute__((weakref ("uv4"))); +static vtype Wv4a __attribute__((weakref ("uv4"))); static vtype *pv4a USED = &Wv4a; static vtype *pv4 USED = &uv4; -extern vtype Wv5a __attribute__((weakref ("uv5"))); +static vtype Wv5a __attribute__((weakref ("uv5"))); static vtype *pv5a USED = &Wv5a; extern vtype uv5; static vtype *pv5 USED = &uv5; -extern vtype Wv6a __attribute__((weakref ("wv6"))); +static vtype Wv6a __attribute__((weakref ("wv6"))); static vtype *pv6a USED = &Wv6a; extern vtype wv6; -extern vtype Wv7a __attribute__((weakref ("uv7"))); +static vtype Wv7a __attribute__((weakref ("uv7"))); static vtype* USED fv7 (void) { return &Wv7a; } @@ -69,71 +66,69 @@ extern vtype uv8; static vtype* USED fv8a (void) { return &uv8; } -extern vtype Wv8a __attribute__((weakref ("uv8"))); +static vtype Wv8a __attribute__((weakref ("uv8"))); static vtype* USED fv8 (void) { return &Wv8a; } extern vtype wv9 __attribute__((weak)); -extern vtype Wv9a __attribute__((weakref ("wv9"))); +static vtype Wv9a __attribute__((weakref ("wv9"))); static vtype *pv9a USED = &Wv9a; -extern vtype Wv10a __attribute__((weakref ("Wv10b"))); -extern vtype Wv10b __attribute__((weakref ("Wv10c"))); -extern vtype Wv10c __attribute__((weakref ("Wv10d"))); -extern vtype Wv10d __attribute__((weakref ("wv10"))); +static vtype Wv10a __attribute__((weakref ("Wv10b"))); +static vtype Wv10b __attribute__((weakref ("Wv10c"))); +static vtype Wv10c __attribute__((weakref ("Wv10d"))); +static vtype Wv10d __attribute__((weakref ("wv10"))); extern vtype wv10; extern vtype wv11; -extern vtype Wv11d __attribute__((weakref ("wv11"))); -extern vtype Wv11c __attribute__((weakref ("Wv11d"))); -extern vtype Wv11b __attribute__((weakref ("Wv11c"))); -extern vtype Wv11a __attribute__((weakref ("Wv11b"))); +static vtype Wv11d __attribute__((weakref ("wv11"))); +static vtype Wv11c __attribute__((weakref ("Wv11d"))); +static vtype Wv11b __attribute__((weakref ("Wv11c"))); +static vtype Wv11a __attribute__((weakref ("Wv11b"))); -extern vtype Wv12 __attribute__((weakref ("wv12"))); +static vtype Wv12 __attribute__((weakref ("wv12"))); extern vtype wv12 __attribute__((weak)); -extern vtype Wv13 __attribute__((weakref ("wv13"))); +static vtype Wv13 __attribute__((weakref ("wv13"))); extern vtype wv13 __attribute__((weak)); -extern vtype Wv14a __attribute__((weakref ("wv14"))); -extern vtype Wv14b __attribute__((weakref ("wv14"))); +static vtype Wv14a __attribute__((weakref ("wv14"))); +static vtype Wv14b __attribute__((weakref ("wv14"))); extern vtype wv14 __attribute__((weak)); typedef void ftype(void); extern ftype wf1; -extern ftype Wf1a __attribute__((weakref ("wf1"))); +static ftype Wf1a __attribute__((weakref ("wf1"))); static ftype *pf1a USED = &Wf1a; -extern ftype Wf1b __attribute__((weak, weakref, alias ("wf1"))); -static ftype *pf1b USED = &Wf1b; -extern ftype Wf1c __attribute__((weakref)); +static ftype Wf1c __attribute__((weakref)); extern ftype Wf1c __attribute__((alias ("wf1"))); static ftype *pf1c USED = &Wf1c; void gf2(void) {} -extern ftype Wf2a __attribute__((weakref ("gf2"))); +static ftype Wf2a __attribute__((weakref ("gf2"))); static ftype *pf2a USED = &Wf2a; static void lf3(void) {} -extern ftype Wf3a __attribute__((weakref ("lf3"))); +static ftype Wf3a __attribute__((weakref ("lf3"))); static ftype *pf3a USED = &Wf3a; extern ftype uf4; -extern ftype Wf4a __attribute__((weakref ("uf4"))); +static ftype Wf4a __attribute__((weakref ("uf4"))); static ftype *pf4a USED = &Wf4a; static ftype *pf4 USED = &uf4; -extern ftype Wf5a __attribute__((weakref ("uf5"))); +static ftype Wf5a __attribute__((weakref ("uf5"))); static ftype *pf5a USED = &Wf5a; extern ftype uf5; static ftype *pf5 USED = &uf5; -extern ftype Wf6a __attribute__((weakref ("wf6"))); +static ftype Wf6a __attribute__((weakref ("wf6"))); static ftype *pf6a USED = &Wf6a; extern ftype wf6; -extern ftype Wf7a __attribute__((weakref ("uf7"))); +static ftype Wf7a __attribute__((weakref ("uf7"))); static ftype* USED ff7 (void) { return &Wf7a; } @@ -146,43 +141,45 @@ extern ftype uf8; static ftype* USED ff8a (void) { return &uf8; } -extern ftype Wf8a __attribute__((weakref ("uf8"))); +static ftype Wf8a __attribute__((weakref ("uf8"))); static ftype* USED ff8 (void) { return &Wf8a; } extern ftype wf9 __attribute__((weak)); -extern ftype Wf9a __attribute__((weakref ("wf9"))); +static ftype Wf9a __attribute__((weakref ("wf9"))); static ftype *pf9a USED = &Wf9a; -extern ftype Wf10a __attribute__((weakref ("Wf10b"))); -extern ftype Wf10b __attribute__((weakref ("Wf10c"))); -extern ftype Wf10c __attribute__((weakref ("Wf10d"))); -extern ftype Wf10d __attribute__((weakref ("wf10"))); +static ftype Wf10a __attribute__((weakref ("Wf10b"))); +static ftype Wf10b __attribute__((weakref ("Wf10c"))); +static ftype Wf10c __attribute__((weakref ("Wf10d"))); +static ftype Wf10d __attribute__((weakref ("wf10"))); extern ftype wf10; extern ftype wf11; -extern ftype Wf11d __attribute__((weakref ("wf11"))); -extern ftype Wf11c __attribute__((weakref ("Wf11d"))); -extern ftype Wf11b __attribute__((weakref ("Wf11c"))); -extern ftype Wf11a __attribute__((weakref ("Wf11b"))); +static ftype Wf11d __attribute__((weakref ("wf11"))); +static ftype Wf11c __attribute__((weakref ("Wf11d"))); +static ftype Wf11b __attribute__((weakref ("Wf11c"))); +static ftype Wf11a __attribute__((weakref ("Wf11b"))); -extern ftype Wf12 __attribute__((weakref ("wf12"))); +static ftype Wf12 __attribute__((weakref ("wf12"))); extern ftype wf12 __attribute__((weak)); -extern ftype Wf13 __attribute__((weakref ("wf13"))); +static ftype Wf13 __attribute__((weakref ("wf13"))); extern ftype wf13 __attribute__((weak)); -extern ftype Wf14a __attribute__((weakref ("wf14"))); -extern ftype Wf14b __attribute__((weakref ("wf14"))); +static ftype Wf14a __attribute__((weakref ("wf14"))); +static ftype Wf14b __attribute__((weakref ("wf14"))); extern ftype wf14 __attribute__((weak)); +#ifndef __APPLE__ #define chk(p) do { if (!p) abort (); } while (0) +#else +#define chk(p) /* */ +#endif int main () { chk (!pv1a); - chk (!pv1b); - chk (!pv1c); chk (pv2a); chk (pv3a); chk (pv4a); @@ -203,7 +200,6 @@ int main () { chk (!&Wv14a); chk (!pf1a); - chk (!pf1b); chk (!pf1c); chk (pf2a); chk (pf3a); diff --git a/gcc/testsuite/gcc.dg/attr-weakref-1b.c b/gcc/testsuite/gcc.dg/attr-weakref-1b.c new file mode 100644 index 00000000000..c2c43898c84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-weakref-1b.c @@ -0,0 +1,20 @@ +/* On Darwin, you have to have a definition of the function to link, + even if later on it won't be present in some dylib. (That is, + you have to link with the latest version of the dylib.) */ +void wf1(void) { } +void wf6(void) { } +void wf9(void) { } +void wf10(void) { } +void wf11(void) { } +void wf12(void) { } +void wf13(void) { } +void wf14(void) { } + +int wv1; +int wv6; +int wv9; +int wv10; +int wv11; +int wv12; +int wv13; +int wv14; diff --git a/gcc/testsuite/gcc.dg/attr-weakref-2.c b/gcc/testsuite/gcc.dg/attr-weakref-2.c new file mode 100644 index 00000000000..75cc0779c57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-weakref-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-weak "" } */ + +typedef int vtype; + +extern vtype wv1; +extern vtype Wv1a __attribute__((weakref ("wv1"))); /* { dg-error "weakref 'Wv1a' must have static linkage" } */ diff --git a/gcc/testsuite/gcc.dg/darwin-weakref-1.c b/gcc/testsuite/gcc.dg/darwin-weakref-1.c new file mode 100644 index 00000000000..22a3cc079a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/darwin-weakref-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile { target *-*-darwin* } } */ +// { dg-require-weak "" } +// { dg-options "-O2" } +// { dg-options "-O2 -mmacosx-version-min=10.2" { target { powerpc-*-darwin* } } } +/* { dg-final { scan-assembler "weak_reference _wv1" } } */ +/* { dg-final { scan-assembler "weak_reference _wf1" } } */ +/* { dg-final { scan-assembler-not "weak_reference _w.2" } } */ + + +typedef int vtype; + +extern vtype wv1; +static vtype Wv1a __attribute__((weakref ("wv1"))); +vtype *pv1a = &Wv1a; + +extern vtype wv2; +static vtype Wv2a __attribute__((weakref ("wv2"))); +vtype *pv2a = &wv2; + +typedef void ftype(void); + +extern ftype wf1; +static ftype Wf1a __attribute__((weakref ("wf1"))); +ftype *pf1a = &Wf1a; + +extern ftype wf2; +static ftype Wf2a __attribute__((weakref ("wf2"))); +ftype *pf2a = &wf2; diff --git a/gcc/varasm.c b/gcc/varasm.c index fa181e17f1e..5e59f3a1a92 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4508,10 +4508,6 @@ weak_finish_1 (tree decl) if (! TREE_USED (decl)) return; - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)) - && lookup_attribute ("alias", DECL_ATTRIBUTES (decl))) - return; - #ifdef ASM_WEAKEN_DECL ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL); #else @@ -4878,6 +4874,8 @@ assemble_alias (tree decl, tree target) TREE_CHAIN (alias) = target; #endif } + if (TREE_PUBLIC (decl)) + error ("weakref %q+D must have static linkage", decl); } else { @@ -5619,21 +5617,29 @@ default_binds_local_p_1 (tree exp, int shlib) /* A non-decl is an entry in the constant pool. */ if (!DECL_P (exp)) local_p = true; + /* Weakrefs may not bind locally, even though the weakref itself is + always static and therefore local. */ + else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))) + local_p = false; /* Static variables are always local. */ else if (! TREE_PUBLIC (exp)) local_p = true; - /* A variable is local if the user explicitly tells us so. */ - else if (DECL_VISIBILITY_SPECIFIED (exp) && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) + /* A variable is local if the user has said explicitly that it will + be. */ + else if (DECL_VISIBILITY_SPECIFIED (exp) + && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) local_p = true; - /* Otherwise, variables defined outside this object may not be local. */ + /* Variables defined outside this object might not be local. */ else if (DECL_EXTERNAL (exp)) local_p = false; - /* Linkonce and weak data are never local. */ - else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp)) - local_p = false; - /* If none of the above and visibility is not default, make local. */ + /* If defined in this object and visibility is not default, must be + local. */ else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) local_p = true; + /* Default visibility weak data can be overridden by a strong symbol + in another module and so are not local. */ + else if (DECL_WEAK (exp)) + local_p = false; /* If PIC, then assume that any global name can be overridden by symbols resolved from other modules. */ else if (shlib)