aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-05-08 14:37:55 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-05-08 14:37:55 +0000
commitf90bf7ca71a530cd66960fecf3b38ffe420d713e (patch)
treee29282f7d185b01464fe3cb43ca3cccca118645a /gcc
parent61b8fbecf711195d0b9be7cc56fd2ed5030b97e0 (diff)
downloadgcc-f90bf7ca71a530cd66960fecf3b38ffe420d713e.zip
gcc-f90bf7ca71a530cd66960fecf3b38ffe420d713e.tar.gz
gcc-f90bf7ca71a530cd66960fecf3b38ffe420d713e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/weak-3.c8
-rw-r--r--gcc/testsuite/gcc.dg/weak-5.c4
-rw-r--r--gcc/varasm.c76
5 files changed, 78 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 686cace..2df3656 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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>
* cse.c (dead_libcall_p): Update counts.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c231d99..c1dc849 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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>
* 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 bd7d827..1675ab1 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 694eb61..eec2109 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 2215fdd..a463fb3 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. */