This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix PR6569
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 08 May 2002 07:45:27 -0700
- Subject: PATCH: Fix PR6569
This patch fixes PR6569, a high-priority regression on 20011119-2.c on
Solaris.
Tested by lots of people (thanks!) on lots of platforms; by me with a
bootstrap and make check on i686-pc-linux-gnu.
Applied on the mainline and on the branch.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2002-05-08 Mark Mitchell <mark@codesourcery.com>
PR c/6569.
* varasm.c (mark_weak): New function.
(merge_weak): Use it. Do not call declare_weak.
(declare_weak): Use merge_weak.
2002-05-08 Mark Mitchell <mark@codesourcery.com>
PR c/6569
* gcc.dg/weak-3.c: Update location of warning messages.
* gcc.dg/weak-5.c: Likewise.
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 8 May 2002 14:32:12 -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. */
Index: testsuite/gcc.dg/weak-3.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/weak-3.c,v
retrieving revision 1.1.2.1
diff -c -p -r1.1.2.1 weak-3.c
*** testsuite/gcc.dg/weak-3.c 28 Apr 2002 18:43:58 -0000 1.1.2.1
--- testsuite/gcc.dg/weak-3.c 8 May 2002 14:34:20 -0000
*************** void * foo1b (void)
*** 34,45 ****
}
! extern void * ffoo1c (void); /* { dg-warning "weak declaration" "weak
declaration" } */
void * foo1c (void)
{
return (void *)ffoo1c;
}
! extern void * ffoo1c (void) __attribute__((weak));
int ffoo1d (void);
--- 34,45 ----
}
! extern void * ffoo1c (void);
void * foo1c (void)
{
return (void *)ffoo1c;
}
! extern void * ffoo1c (void) __attribute__((weak)); /* { dg-warning "weak
declaration" "weak declaration" } */
int ffoo1d (void);
*************** void * foo1e (void)
*** 56,62 ****
}
! extern void * ffoo1f (void); /* { dg-warning "weak declaration" "weak
declaration" } */
extern void * ffoox1f (void);
void * foo1f (void)
{
--- 56,62 ----
}
! extern void * ffoo1f (void);
extern void * ffoox1f (void);
void * foo1f (void)
{
*************** void * foo1f (void)
*** 64,70 ****
ffoo1f ();
return 0;
}
! extern void * ffoo1f (void) __attribute__((weak, alias ("ffoox1f")));
extern void * ffoo1g (void);
--- 64,70 ----
ffoo1f ();
return 0;
}
! extern void * ffoo1f (void) __attribute__((weak, alias ("ffoox1f"))); /*
{ dg-warning "weak declaration" "weak declaration" } */
extern void * ffoo1g (void);
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.1
diff -c -p -r1.1.2.1 weak-5.c
*** testsuite/gcc.dg/weak-5.c 28 Apr 2002 18:43:58 -0000 1.1.2.1
--- testsuite/gcc.dg/weak-5.c 8 May 2002 14:34:20 -0000
*************** void * foo1b (void)
*** 39,50 ****
}
! extern int vfoo1c; /* { dg-warning "weak declaration" "weak declaration"
} */
void * foo1c (void)
{
return (void *)&vfoo1c;
}
! extern int vfoo1c __attribute__((weak));
extern int vfoo1d __attribute__((weak));
--- 39,50 ----
}
! extern int vfoo1c;
void * foo1c (void)
{
return (void *)&vfoo1c;
}
! extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak
declaration" "weak declaration" } */
extern int vfoo1d __attribute__((weak));