Index: gcc/c-decl.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-decl.c,v retrieving revision 1.300.2.6 diff -u -p -r1.300.2.6 c-decl.c --- gcc/c-decl.c 26 Apr 2002 00:23:32 -0000 1.300.2.6 +++ gcc/c-decl.c 28 Apr 2002 09:20:07 -0000 @@ -1955,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, diffe } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + /* For functions, static overrides non-static. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) { Index: gcc/c-pragma.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-pragma.c,v retrieving revision 1.46.6.3 diff -u -p -r1.46.6.3 c-pragma.c --- gcc/c-pragma.c 22 Mar 2002 22:49:38 -0000 1.46.6.3 +++ gcc/c-pragma.c 28 Apr 2002 09:20:07 -0000 @@ -287,6 +287,10 @@ apply_pragma_weak (decl, 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 may result in unspecified behaviour"); + declare_weak (decl); } Index: gcc/output.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/output.h,v retrieving revision 1.94.2.1 diff -u -p -r1.94.2.1 output.h --- gcc/output.h 23 Apr 2002 08:11:21 -0000 1.94.2.1 +++ gcc/output.h 28 Apr 2002 09:20:07 -0000 @@ -231,6 +231,8 @@ extern void mergeable_constant_section P /* Declare DECL to be a weak symbol. */ extern void declare_weak PARAMS ((tree)); +/* Merge weak status. */ +extern void merge_weak PARAMS ((tree, tree)); #endif /* TREE_CODE */ /* Emit any pending weak declarations. */ Index: gcc/varasm.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/varasm.c,v retrieving revision 1.250.2.7 diff -u -p -r1.250.2.7 varasm.c --- gcc/varasm.c 25 Mar 2002 00:54:26 -0000 1.250.2.7 +++ gcc/varasm.c 28 Apr 2002 09:20:07 -0000 @@ -4990,6 +4990,32 @@ output_constructor (exp, size, align) to be emitted. */ static tree weak_decls; +/* Merge weak status between NEWDECL and OLDDECL. */ + +void +merge_weak (newdecl, olddecl) + tree newdecl; + tree olddecl; +{ + tree decl; + + if ((! DECL_WEAK (newdecl) && ! DECL_WEAK (olddecl)) + || (DECL_WEAK (newdecl) && DECL_WEAK (olddecl))) + return; + + decl = DECL_WEAK (olddecl) ? newdecl : olddecl; + + if (SUPPORTS_WEAK + && DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl) + && (TREE_CODE (decl) != VAR_DECL + || ! TREE_STATIC (decl)) + && TREE_USED (decl) + && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + warning_with_decl (decl, "weak declaration of `%s' after first use may result in unspecified behaviour"); + + declare_weak (decl); +} + /* Declare DECL to be a weak symbol. */ void @@ -4998,7 +5024,7 @@ declare_weak (decl) { if (! TREE_PUBLIC (decl)) error_with_decl (decl, "weak declaration of `%s' must be public"); - else if (TREE_ASM_WRITTEN (decl)) + else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) error_with_decl (decl, "weak declaration of `%s' must precede definition"); else if (SUPPORTS_WEAK) { @@ -5009,6 +5035,12 @@ declare_weak (decl) warning_with_decl (decl, "weak declaration of `%s' not supported"); DECL_WEAK (decl) = 1; + + if (DECL_RTL_SET_P (decl) + && GET_CODE (DECL_RTL (decl)) == MEM + && XEXP (DECL_RTL (decl), 0) + && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF) + SYMBOL_REF_WEAK (XEXP (DECL_RTL (decl), 0)) = 1; } /* Emit any pending weak declarations. */ Index: gcc/cp/decl.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v retrieving revision 1.866.2.25 diff -u -p -r1.866.2.25 decl.c --- gcc/cp/decl.c 23 Apr 2002 23:52:07 -0000 1.866.2.25 +++ gcc/cp/decl.c 28 Apr 2002 09:20:08 -0000 @@ -3645,7 +3645,8 @@ duplicate_decls (newdecl, olddecl) } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl); TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);