This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: #pragma weak is broken in 3.1, partail fix
- From: Richard Henderson <rth at redhat dot com>
- To: Marc Espie <espie at nerim dot net>, gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Sun, 26 May 2002 22:53:08 -0700
- Subject: Re: #pragma weak is broken in 3.1, partail fix
- References: <20020521165708.A6328@tetto.liafa.jussieu.fr> <20020521113149.C24775@redhat.com> <20020525105538.A10964@tetto.liafa.jussieu.fr> <20020525204334.A28290@redhat.com>
The following is what I applied to 3.1. It backports some of
the visibility attribute changes from mainline that, as a side
effect, fixed some of the problems with weak aliases.
Tested on alphaev6 and i386 linux.
r~
2002-05-25 Richard Henderson <rth@redhat.com>
* c-pragma.c (apply_pragma_weak): Convert value identifier to
string for decl_attributes.
(handle_pragma_weak): Call assemble_alias if we're modifying
an existing decl.
* gcc.dg/weak-9.c: New.
2002-05-15 Richard Henderson <rth@redhat.com>
* varasm.c (merge_weak): Remove special case for extern and common.
2002-05-15 Richard Henderson <rth@redhat.com>
* varasm.c (merge_weak): Error for any weakening after definition.
Adjust weakening after use warning to catch more cases.
(assemble_alias): Set TREE_USED and TREE_ASM_WRITTEN consistently.
* config/alpha/alpha.c (alpha_encode_section_info): Do not abort.
* gcc.dg/weak-5.c (vfoo1c): No warning here.
(vfoo1f): Warning here.
(vfoo1l): Don't redefine the alias.
2002-03-02 Richard Henderson <rth@redhat.com>
* attribs.c (handle_alias_attribute): Don't call assemble_alias.
* toplev.c (rest_of_decl_compilation): Invoke assemble_alias when
needed.
Index: attribs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/attribs.c,v
retrieving revision 1.13
diff -c -p -d -r1.13 attribs.c
*** attribs.c 25 Feb 2002 22:38:52 -0000 1.13
--- attribs.c 27 May 2002 05:41:52 -0000
*************** handle_alias_attribute (node, name, args
*** 1050,1056 ****
DECL_INITIAL (decl) = error_mark_node;
else
DECL_EXTERNAL (decl) = 0;
- assemble_alias (decl, id);
}
else
{
--- 1050,1055 ----
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.46.6.4
diff -c -p -d -r1.46.6.4 c-pragma.c
*** c-pragma.c 28 Apr 2002 18:43:53 -0000 1.46.6.4
--- c-pragma.c 27 May 2002 05:41:52 -0000
*************** apply_pragma_weak (decl, value)
*** 284,292 ****
tree decl, value;
{
if (value)
! decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
! build_tree_list (NULL, value)),
! 0);
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
--- 284,297 ----
tree decl, value;
{
if (value)
! {
! value = build_string (IDENTIFIER_LENGTH (value),
! IDENTIFIER_POINTER (value));
! decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
! build_tree_list (NULL, value)),
! 0);
! }
!
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
*************** handle_pragma_weak (dummy)
*** 343,349 ****
decl = identifier_global_value (name);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
! apply_pragma_weak (decl, value);
else
pending_weaks = tree_cons (name, value, pending_weaks);
}
--- 348,358 ----
decl = identifier_global_value (name);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
! {
! apply_pragma_weak (decl, value);
! if (value)
! assemble_alias (decl, value);
! }
else
pending_weaks = tree_cons (name, value, pending_weaks);
}
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.574.2.15
diff -c -p -d -r1.574.2.15 toplev.c
*** toplev.c 23 May 2002 17:57:28 -0000 1.574.2.15
--- toplev.c 27 May 2002 05:41:53 -0000
*************** rest_of_decl_compilation (decl, asmspec,
*** 2248,2253 ****
--- 2248,2266 ----
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
#endif
+ /* We deferred calling assemble_alias so that we could collect
+ other attributes such as visibility. Emit the alias now. */
+ {
+ tree alias;
+ alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+ if (alias)
+ {
+ alias = TREE_VALUE (TREE_VALUE (alias));
+ alias = get_identifier (TREE_STRING_POINTER (alias));
+ assemble_alias (decl, alias);
+ }
+ }
+
/* Forward declarations for nested functions are not "external",
but we need to treat them as if they were. */
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.250.2.12
diff -c -p -d -r1.250.2.12 varasm.c
*** varasm.c 24 May 2002 19:22:08 -0000 1.250.2.12
--- varasm.c 27 May 2002 05:41:53 -0000
*************** merge_weak (newdecl, olddecl)
*** 5017,5030 ****
if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
return;
- if (SUPPORTS_WEAK
- && DECL_WEAK (newdecl)
- && DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)
- && (TREE_CODE (olddecl) != VAR_DECL || ! TREE_STATIC (olddecl))
- && TREE_USED (olddecl)
- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
- warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
-
if (DECL_WEAK (newdecl))
{
tree wd;
--- 5017,5022 ----
*************** merge_weak (newdecl, olddecl)
*** 5035,5044 ****
go back and make it weak. This error cannot caught in
declare_weak because the NEWDECL and OLDDECL was not yet
been merged; therefore, TREE_ASM_WRITTEN was not set. */
! if (TREE_CODE (olddecl) == FUNCTION_DECL && TREE_ASM_WRITTEN (olddecl))
error_with_decl (newdecl,
"weak declaration of `%s' must precede definition");
!
if (SUPPORTS_WEAK)
{
/* We put the NEWDECL on the weak_decls list at some point.
--- 5027,5043 ----
go back and make it weak. This error cannot caught in
declare_weak because the NEWDECL and OLDDECL was not yet
been merged; therefore, TREE_ASM_WRITTEN was not set. */
! if (TREE_ASM_WRITTEN (olddecl))
error_with_decl (newdecl,
"weak declaration of `%s' must precede definition");
!
! /* If we've already generated rtl referencing OLDDECL, we may
! have done so in a way that will not function properly with
! a weak symbol. */
! else if (TREE_USED (olddecl)
! && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
! warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
!
if (SUPPORTS_WEAK)
{
/* We put the NEWDECL on the weak_decls list at some point.
*************** assemble_alias (decl, target)
*** 5175,5181 ****
#else
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
- TREE_ASM_WRITTEN (decl) = 1;
#else /* !ASM_OUTPUT_DEF */
#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
if (! DECL_WEAK (decl))
--- 5174,5179 ----
*************** assemble_alias (decl, target)
*** 5186,5196 ****
#else
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
- TREE_ASM_WRITTEN (decl) = 1;
#else
warning ("alias definitions not supported in this configuration; ignored");
#endif
#endif
}
/* Returns 1 if the target configuration supports defining public symbols
--- 5184,5197 ----
#else
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
#else
warning ("alias definitions not supported in this configuration; ignored");
#endif
#endif
+
+ TREE_USED (decl) = 1;
+ TREE_ASM_WRITTEN (decl) = 1;
+ TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
}
/* Returns 1 if the target configuration supports defining public symbols
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.233.2.9
diff -c -p -d -r1.233.2.9 alpha.c
*** config/alpha/alpha.c 10 Apr 2002 05:14:54 -0000 1.233.2.9
--- config/alpha/alpha.c 27 May 2002 05:41:53 -0000
*************** alpha_encode_section_info (decl)
*** 1664,1670 ****
XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
}
else if (symbol_str[0] == '@')
! abort ();
}
/* legitimate_address_p recognizes an RTL expression that is a valid
--- 1664,1674 ----
XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
}
else if (symbol_str[0] == '@')
! {
! /* We're hosed. This can happen when the user adds a weak
! attribute after rtl generation. They should have gotten
! a warning about unspecified behaviour from varasm.c. */
! }
}
/* legitimate_address_p recognizes an RTL expression that is a valid
Index: testsuite/gcc.dg/weak-5.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/weak-5.c,v
retrieving revision 1.1.2.3
diff -c -p -d -r1.1.2.3 weak-5.c
*** testsuite/gcc.dg/weak-5.c 17 May 2002 04:04:29 -0000 1.1.2.3
--- testsuite/gcc.dg/weak-5.c 27 May 2002 05:41:53 -0000
***************
*** 9,26 ****
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1l" } } */
/* test variable addresses with __attribute__ ((weak)) */
--- 9,26 ----
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1a" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1b" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1c" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1d" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1e" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1f" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1g" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1h" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1i" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1j" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1k" } } */
! /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1l" } } */
/* test variable addresses with __attribute__ ((weak)) */
*************** void * foo1c (void)
*** 45,51 ****
{
return (void *)&vfoo1c;
}
! extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */
extern int vfoo1d __attribute__((weak));
--- 45,51 ----
{
return (void *)&vfoo1c;
}
! extern int vfoo1c __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1d __attribute__((weak));
*************** void * foo1f (void)
*** 69,75 ****
{
return (void *)&vfoo1f;
}
! extern int vfoo1f __attribute__((weak));
extern int vfoo1g;
--- 69,75 ----
{
return (void *)&vfoo1f;
}
! extern int vfoo1f __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1g;
*************** void * foo1g (void)
*** 77,83 ****
{
return (void *)&vfoo1g;
}
! int vfoo1g __attribute__((weak));
extern int vfoo1h __attribute__((weak));
--- 77,83 ----
{
return (void *)&vfoo1g;
}
! int vfoo1g __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
extern int vfoo1h __attribute__((weak));
*************** int vfoo1k = 1;
*** 112,117 ****
int vfoox1l = 1;
- extern int vfoo1l __attribute__((alias ("vfoox1l")));
extern int vfoo1l __attribute__((weak, alias ("vfoox1l")));
-
--- 112,115 ----
Index: testsuite/gcc.dg/weak-9.c
===================================================================
RCS file: testsuite/gcc.dg/weak-9.c
diff -N testsuite/gcc.dg/weak-9.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/weak-9.c 27 May 2002 05:41:53 -0000
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fno-common" } */
+
+ /* COFF does not support weak, and dg doesn't support UNSUPPORTED. */
+ /* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */
+
+ /* { dg-final { global target_triplet } } */
+ /* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
+ /* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } *
+ /
+ /* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f1" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f2" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f3" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f4" } } */
+ /* { dg-final { scan-assembler "notf1" } } */
+ /* { dg-final { scan-assembler "notf2" } } */
+ /* { dg-final { scan-assembler "notf3" } } */
+ /* { dg-final { scan-assembler "notf4" } } */
+
+ void f1() __attribute__((weak, alias("notf1")));
+ void f2() __attribute__((alias("notf2"), weak));
+
+ #pragma weak f3=notf3
+ void f3();
+
+ void f4();
+ #pragma weak f4=notf4