diff options
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index fc45cd8..4dbd09c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4989,6 +4989,31 @@ 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)) + 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 results in unspecified behavior"); + + declare_weak (decl); +} + /* Declare DECL to be a weak symbol. */ void @@ -4997,7 +5022,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) { @@ -5008,6 +5033,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. */ |