target/6569: sparc-sun-solaris2.7 C testsuite regression in compile/20011119-2.c
Mark Mitchell
mark@codesourcery.com
Tue May 7 12:45:00 GMT 2002
--On Tuesday, May 07, 2002 07:24:48 PM +0200 Franz Sirl
<Franz.Sirl-kernel@lauterbach.com> wrote:
Don't worry; we'll get it fixed.
The problem is that there are multiple declarations of functions involved.
If you say:
void f()
void f() __attribute__((weak));
The C front end makes two DECLs for f. Then, it calls duplicate_decls to
smush them together; it always throws away the new one and keeps the old.
We're getting the new one on the weak_decls list sometimes, and that's
messing things up.
This patch will fix it; I'm testing on x86 now, and if someone can
kick off a SPARC run that would be great. As a special bonus, this
also makes the warnings come out in the right place consistently.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.co
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.250.2.9
diff -c -p -r1.250.2.9 varasm.c
*** varasm.c 1 May 2002 18:03:34 -0000 1.250.2.9
--- varasm.c 7 May 2002 18:18:46 -0000
*************** static int const_str_htab_eq PARAMS ((c
*** 187,192 ****
--- 187,193 ----
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
*************** output_constructor (exp, size, align)
*** 4990,4995 ****
--- 4991,5011 ----
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
*************** merge_weak (newdecl, olddecl)
*** 4997,5018 ****
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. */
--- 5013,5066 ----
tree newdecl;
tree olddecl;
{
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;
!
! /* 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. */
! }
!
! /* 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. */
*************** declare_weak (decl)
*** 5033,5045 ****
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;
}
/* Emit any pending weak declarations. */
--- 5081,5087 ----
else
warning_with_decl (decl, "weak declaration of `%s' not supported");
! mark_weak (decl);
}
/* Emit any pending weak declarations. */
More information about the Gcc-bugs
mailing list