From: Mark Mitchell Date: Wed, 8 May 2002 14:37:55 +0000 (+0000) Subject: re PR target/6569 (sparc-sun-solaris2.7 C testsuite regression in compile/20011119... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f90bf7ca71a530cd66960fecf3b38ffe420d713e;p=gcc.git re PR target/6569 (sparc-sun-solaris2.7 C testsuite regression in compile/20011119-2.c) PR c/6569. * varasm.c (mark_weak): New function. (merge_weak): Use it. Do not call declare_weak. (declare_weak): Use merge_weak. PR c/6569 * gcc.dg/weak-3.c: Update location of warning messages. * gcc.dg/weak-5.c: Likewise. From-SVN: r53293 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 686cacebee1..2df36563dcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-05-08 Mark Mitchell + + PR c/6569. + * varasm.c (mark_weak): New function. + (merge_weak): Use it. Do not call declare_weak. + (declare_weak): Use merge_weak. + Wed May 8 13:12:11 CEST 2002 Jan Hubicka * cse.c (dead_libcall_p): Update counts. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c231d99be32..c1dc8493357 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2002-05-08 Mark Mitchell + + PR c/6569 + * gcc.dg/weak-3.c: Update location of warning messages. + * gcc.dg/weak-5.c: Likewise. + 2002-05-06 Roger Sayle * gcc.c-torture/execute/20020506-1.c: New test case. diff --git a/gcc/testsuite/gcc.dg/weak-3.c b/gcc/testsuite/gcc.dg/weak-3.c index bd7d827ee97..1675ab10f3b 100644 --- a/gcc/testsuite/gcc.dg/weak-3.c +++ b/gcc/testsuite/gcc.dg/weak-3.c @@ -34,12 +34,12 @@ void * foo1b (void) } -extern void * ffoo1c (void); /* { dg-warning "weak declaration" "weak declaration" } */ +extern void * ffoo1c (void); void * foo1c (void) { return (void *)ffoo1c; } -extern void * ffoo1c (void) __attribute__((weak)); +extern void * ffoo1c (void) __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */ int ffoo1d (void); @@ -56,7 +56,7 @@ void * foo1e (void) } -extern void * ffoo1f (void); /* { dg-warning "weak declaration" "weak declaration" } */ +extern void * ffoo1f (void); extern void * ffoox1f (void); void * foo1f (void) { @@ -64,7 +64,7 @@ void * foo1f (void) ffoo1f (); return 0; } -extern void * ffoo1f (void) __attribute__((weak, alias ("ffoox1f"))); +extern void * ffoo1f (void) __attribute__((weak, alias ("ffoox1f"))); /* { dg-warning "weak declaration" "weak declaration" } */ extern void * ffoo1g (void); diff --git a/gcc/testsuite/gcc.dg/weak-5.c b/gcc/testsuite/gcc.dg/weak-5.c index 694eb61ac1c..eec210992f4 100644 --- a/gcc/testsuite/gcc.dg/weak-5.c +++ b/gcc/testsuite/gcc.dg/weak-5.c @@ -39,12 +39,12 @@ void * foo1b (void) } -extern int vfoo1c; /* { dg-warning "weak declaration" "weak declaration" } */ +extern int vfoo1c; void * foo1c (void) { return (void *)&vfoo1c; } -extern int vfoo1c __attribute__((weak)); +extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */ extern int vfoo1d __attribute__((weak)); diff --git a/gcc/varasm.c b/gcc/varasm.c index 2215fdd1969..a463fb39cae 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -189,6 +189,7 @@ static int const_str_htab_eq PARAMS ((const void *x, const void *y)); static void const_str_htab_del PARAMS ((void *)); static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int)); static void resolve_unique_section PARAMS ((tree, int)); +static void mark_weak PARAMS ((tree)); static enum in_section { no_section, in_text, in_data, in_named #ifdef BSS_SECTION_ASM_OP @@ -4993,6 +4994,21 @@ output_constructor (exp, size, align) to be emitted. */ static tree weak_decls; +/* Mark DECL as weak. */ + +static void +mark_weak (decl) + tree decl; +{ + 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; +} + /* Merge weak status between NEWDECL and OLDDECL. */ void @@ -5000,22 +5016,54 @@ 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_WEAK (newdecl) && 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"); + && (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; + + /* NEWDECL is weak, but OLDDECL is not. */ + + /* If we already output the OLDDECL, we're in trouble; we can't + 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. + Replace it with the OLDDECL. */ + for (wd = weak_decls; wd; wd = TREE_CHAIN (wd)) + if (TREE_VALUE (wd) == newdecl) + { + TREE_VALUE (wd) = olddecl; + break; + } + /* We may not find the entry on the list. If NEWDECL is a + weak alias, then we will have already called + globalize_decl to remove the entry; in that case, we do + not need to do anything. */ + } - declare_weak (decl); + /* Make the OLDDECL weak; it's OLDDECL that we'll be keeping. */ + mark_weak (olddecl); + } + else + /* OLDDECL was weak, but NEWDECL was not explicitly marked as + weak. Just update NEWDECL to indicate that it's weak too. */ + mark_weak (newdecl); } /* Declare DECL to be a weak symbol. */ @@ -5036,13 +5084,7 @@ declare_weak (decl) else 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; + mark_weak (decl); } /* Emit any pending weak declarations. */