Commit f90bf7ca by Mark Mitchell Committed by Mark Mitchell

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
parent 61b8fbec
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.
Wed May 8 13:12:11 CEST 2002 Jan Hubicka <jh@suse.cz> Wed May 8 13:12:11 CEST 2002 Jan Hubicka <jh@suse.cz>
* cse.c (dead_libcall_p): Update counts. * cse.c (dead_libcall_p): Update counts.
......
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.
2002-05-06 Roger Sayle <roger@eyesopen.com> 2002-05-06 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/20020506-1.c: New test case. * gcc.c-torture/execute/20020506-1.c: New test case.
......
...@@ -34,12 +34,12 @@ void * foo1b (void) ...@@ -34,12 +34,12 @@ void * foo1b (void)
} }
extern void * ffoo1c (void); /* { dg-warning "weak declaration" "weak declaration" } */ extern void * ffoo1c (void);
void * foo1c (void) void * foo1c (void)
{ {
return (void *)ffoo1c; return (void *)ffoo1c;
} }
extern void * ffoo1c (void) __attribute__((weak)); extern void * ffoo1c (void) __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */
int ffoo1d (void); int ffoo1d (void);
...@@ -56,7 +56,7 @@ void * foo1e (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); extern void * ffoox1f (void);
void * foo1f (void) void * foo1f (void)
{ {
...@@ -64,7 +64,7 @@ void * foo1f (void) ...@@ -64,7 +64,7 @@ void * foo1f (void)
ffoo1f (); ffoo1f ();
return 0; 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); extern void * ffoo1g (void);
......
...@@ -39,12 +39,12 @@ void * foo1b (void) ...@@ -39,12 +39,12 @@ void * foo1b (void)
} }
extern int vfoo1c; /* { dg-warning "weak declaration" "weak declaration" } */ extern int vfoo1c;
void * foo1c (void) void * foo1c (void)
{ {
return (void *)&vfoo1c; return (void *)&vfoo1c;
} }
extern int vfoo1c __attribute__((weak)); extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */
extern int vfoo1d __attribute__((weak)); extern int vfoo1d __attribute__((weak));
......
...@@ -189,6 +189,7 @@ static int const_str_htab_eq PARAMS ((const void *x, const void *y)); ...@@ -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 const_str_htab_del PARAMS ((void *));
static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int)); static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
static void resolve_unique_section PARAMS ((tree, 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 static enum in_section { no_section, in_text, in_data, in_named
#ifdef BSS_SECTION_ASM_OP #ifdef BSS_SECTION_ASM_OP
...@@ -4993,6 +4994,21 @@ output_constructor (exp, size, align) ...@@ -4993,6 +4994,21 @@ output_constructor (exp, size, align)
to be emitted. */ to be emitted. */
static tree weak_decls; 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. */ /* Merge weak status between NEWDECL and OLDDECL. */
void void
...@@ -5000,22 +5016,54 @@ merge_weak (newdecl, olddecl) ...@@ -5000,22 +5016,54 @@ merge_weak (newdecl, olddecl)
tree newdecl; tree newdecl;
tree olddecl; tree olddecl;
{ {
tree decl;
if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl)) if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
return; return;
decl = DECL_WEAK (olddecl) ? newdecl : olddecl;
if (SUPPORTS_WEAK if (SUPPORTS_WEAK
&& DECL_WEAK (newdecl)
&& DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl) && DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)
&& (TREE_CODE (decl) != VAR_DECL && (TREE_CODE (olddecl) != VAR_DECL || ! TREE_STATIC (olddecl))
|| ! TREE_STATIC (decl)) && TREE_USED (olddecl)
&& TREE_USED (decl) && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
warning_with_decl (decl, "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. */ /* Declare DECL to be a weak symbol. */
...@@ -5036,13 +5084,7 @@ declare_weak (decl) ...@@ -5036,13 +5084,7 @@ declare_weak (decl)
else else
warning_with_decl (decl, "weak declaration of `%s' not supported"); warning_with_decl (decl, "weak declaration of `%s' not supported");
DECL_WEAK (decl) = 1; mark_weak (decl);
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. */ /* Emit any pending weak declarations. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment