From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18221 invoked by alias); 28 Apr 2002 14:39:27 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 18094 invoked from network); 28 Apr 2002 14:39:23 -0000 Received: from unknown (HELO linuxpc1.lauterbach.com) (213.70.137.66) by sources.redhat.com with SMTP; 28 Apr 2002 14:39:23 -0000 Received: (qmail 24716 invoked by uid 82); 28 Apr 2002 14:39:18 -0000 Received: from Franz.Sirl-kernel@lauterbach.com by linuxpc1.lauterbach.com with qmail-scanner-1.01 (inocmd32: /. . Clean. Processed in 1.679096 secs); 28 Apr 2002 14:39:18 -0000 Received: from dsl-213-023-029-121.arcor-ip.net (HELO enzo) (213.23.29.121) by linuxpc1.lauterbach.com with SMTP; 28 Apr 2002 14:39:16 -0000 From: Franz Sirl To: Jason Merrill Subject: Re: [PATCH] Fix PR c/6343 (was: Re: GCC 3.1 Prerelease) Date: Sun, 28 Apr 2002 08:44:00 -0000 Cc: gcc-patches@gcc.gnu.org, Richard Henderson , Alan Modra , Mark Mitchell , gcc@gcc.gnu.org References: <5.1.1.2.2.20020423130143.04a21008@mail.lauterbach.com> <200204252121.58902@enzo.bigblue.local> In-Reply-To: MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="------------Boundary-00=_FR8ABF2O2S7N0UDAY68J" Message-Id: <200204281640.27693@enzo.bigblue.local> X-SW-Source: 2002-04/txt/msg01505.txt.bz2 --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Content-length: 1958 On Thursday 25 April 2002 21:54, Jason Merrill wrote: > >>>>> "Franz" == Franz Sirl writes: > > > > On Wednesday 24 April 2002 22:01, Jason Merrill wrote: > >> The latter. We don't want to warn about the C++ frontend's internal > >> trickery with DECL_WEAK. > > > > What kind of trickery? Can I detect that in declare_weak? > > In the C++ frontend, in general an entity with vague linkage (such as a > template instantion) has DECL_EXTERNAL set until EOF, at which point we > decide what to do with it. If we can't tell whether or not this is the One > True translation unit for the entity, we mark it weak/comdat and emit it as > needed. OK, I added TREE_STATIC to the warning check and this killed the regression. > >> I'd prefer to omit the warning entirely on the branch. > > > > Well, I prefer overzealous warnings over no warning at all in the same > > way I prefer ICEs over miscompiled code :-). Besides that extra warning, > > I'm really satisfied now with my patch otherwise and unless you think > > it's overly complicated to get rid of it, I would like to fix it even for > > the branch. > > The warning should only apply to weak externs; the address of a weak > definition is never 0. That should fix the C++ case above. Ah, there's the forest :-). This cuts down the cases to warn about. I moved the check to a separate merge_weak function so I can check both OLDDECL and NEWDECL. Bootstrapped without regressions on powerpc-linux-gnu and x86-linux-gnu. OK to commit to mainline and branch? Franz. PR c/6343 * c-decl.c (duplicate_decls): Call merge_weak. * c-pragma.c (apply_pragma_weak): Warn about misuse. * output.h (merge_weak): Prototype merge_weak. * varasm.c (merge_weak): New function. (declare_weak): Make sure we don't give an error on VAR_DECLs. Mark RTL with SYMBOL_REF_WEAK. cp: * decl.c (duplicate_decls): Call merge_weak. testsuite: * gcc.dg/weak-[2-7].c: New tests. --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/plain; charset="iso-8859-1"; name="gcc-weaksym-7.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="gcc-weaksym-7.patch" Content-length: 4553 Index: gcc/c-decl.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-decl.c,v retrieving revision 1.300.2.6 diff -u -p -r1.300.2.6 c-decl.c --- gcc/c-decl.c 26 Apr 2002 00:23:32 -0000 1.300.2.6 +++ gcc/c-decl.c 28 Apr 2002 09:20:07 -0000 @@ -1955,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, diffe } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + /* For functions, static overrides non-static. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) { Index: gcc/c-pragma.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/c-pragma.c,v retrieving revision 1.46.6.3 diff -u -p -r1.46.6.3 c-pragma.c --- gcc/c-pragma.c 22 Mar 2002 22:49:38 -0000 1.46.6.3 +++ gcc/c-pragma.c 28 Apr 2002 09:20:07 -0000 @@ -287,6 +287,10 @@ apply_pragma_weak (decl, value) decl_attributes (&decl, build_tree_list (get_identifier ("alias"), build_tree_list (NULL, value)), 0); + if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) + && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + warning_with_decl (decl, "applying #pragma weak `%s' after first use may result in unspecified behaviour"); + declare_weak (decl); } Index: gcc/output.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/output.h,v retrieving revision 1.94.2.1 diff -u -p -r1.94.2.1 output.h --- gcc/output.h 23 Apr 2002 08:11:21 -0000 1.94.2.1 +++ gcc/output.h 28 Apr 2002 09:20:07 -0000 @@ -231,6 +231,8 @@ extern void mergeable_constant_section P /* Declare DECL to be a weak symbol. */ extern void declare_weak PARAMS ((tree)); +/* Merge weak status. */ +extern void merge_weak PARAMS ((tree, tree)); #endif /* TREE_CODE */ /* Emit any pending weak declarations. */ Index: gcc/varasm.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/varasm.c,v retrieving revision 1.250.2.7 diff -u -p -r1.250.2.7 varasm.c --- gcc/varasm.c 25 Mar 2002 00:54:26 -0000 1.250.2.7 +++ gcc/varasm.c 28 Apr 2002 09:20:07 -0000 @@ -4990,6 +4990,32 @@ output_constructor (exp, size, align) to be emitted. */ static tree weak_decls; +/* Merge weak status between NEWDECL and OLDDECL. */ + +void +merge_weak (newdecl, olddecl) + tree newdecl; + tree olddecl; +{ + tree decl; + + if ((! DECL_WEAK (newdecl) && ! DECL_WEAK (olddecl)) + || (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 may result in unspecified behaviour"); + + declare_weak (decl); +} + /* Declare DECL to be a weak symbol. */ void @@ -4998,7 +5024,7 @@ declare_weak (decl) { if (! TREE_PUBLIC (decl)) error_with_decl (decl, "weak declaration of `%s' must be public"); - else if (TREE_ASM_WRITTEN (decl)) + else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) error_with_decl (decl, "weak declaration of `%s' must precede definition"); else if (SUPPORTS_WEAK) { @@ -5009,6 +5035,12 @@ declare_weak (decl) 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. */ Index: gcc/cp/decl.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v retrieving revision 1.866.2.25 diff -u -p -r1.866.2.25 decl.c --- gcc/cp/decl.c 23 Apr 2002 23:52:07 -0000 1.866.2.25 +++ gcc/cp/decl.c 28 Apr 2002 09:20:08 -0000 @@ -3645,7 +3645,8 @@ duplicate_decls (newdecl, olddecl) } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl); TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-2.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-2.c" Content-length: 1397 /* { dg-do compile } */ /* { dg-options "-fno-common" } */ /* COFF does not support weak, and dg doesn't support UNSUPPORTED. */ /* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */ /* { dg-final { global target_triplet } } */ /* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */ /* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */ /* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1a" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1b" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1c" } } */ /* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]ffoo1d" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1e" } } */ /* test function addresses with #pragma weak */ #pragma weak ffoo1a extern void * ffoo1a (void); void * foo1a (void) { return (void *)ffoo1a; } extern void * ffoo1b (void); #pragma weak ffoo1b void * foo1b (void) { return (void *)ffoo1b; } extern void * ffoo1c (void); /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */ void * foo1c (void) { return (void *)ffoo1c; } #pragma weak ffoo1c int ffoo1d (void); #pragma weak ffoo1d extern void * ffoo1e (void); #pragma weak ffoo1e void * foo1e (void) { if (ffoo1e) ffoo1e (); return 0; } --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-3.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-3.c" Content-length: 2133 /* { dg-do compile } */ /* { dg-options "-fno-common" } */ /* COFF does not support weak, and dg doesn't support UNSUPPORTED. */ /* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */ /* { dg-final { global target_triplet } } */ /* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */ /* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */ /* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1a" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1b" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1c" } } */ /* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]ffoo1d" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1e" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1f" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1g" } } */ /* test function addresses with __attribute__((weak)) */ extern void * ffoo1a (void) __attribute__((weak)); extern void * ffoo1a (void); void * foo1a (void) { return (void *)ffoo1a; } extern void * ffoo1b (void); extern void * ffoo1b (void) __attribute__((weak)); void * foo1b (void) { return (void *)ffoo1b; } 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); int ffoo1d (void) __attribute__((weak)); extern void * ffoo1e (void); extern void * ffoo1e (void) __attribute__((weak)); void * foo1e (void) { if (ffoo1e) ffoo1e (); return 0; } extern void * ffoo1f (void); /* { dg-warning "weak declaration" "weak declaration" } */ extern void * ffoox1f (void); void * foo1f (void) { if (ffoo1f) ffoo1f (); return 0; } extern void * ffoo1f (void) __attribute__((weak, alias ("ffoox1f"))); extern void * ffoo1g (void); extern void * ffoox1g (void); extern void * ffoo1g (void) __attribute__((weak, alias ("ffoox1g"))); void * foo1g (void) { if (ffoo1g) ffoo1g (); return 0; } --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-5.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-5.c" Content-length: 2807 /* { dg-do compile } */ /* { dg-options "-fno-common" } */ /* COFF does not support weak, and dg doesn't support UNSUPPORTED. */ /* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */ /* { dg-final { global target_triplet } } */ /* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */ /* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */ /* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1l" } } */ /* test variable addresses with __attribute__ ((weak)) */ extern int vfoo1a __attribute__((weak)); extern int vfoo1a; void * foo1a (void) { return (void *)&vfoo1a; } extern int vfoo1b; extern int vfoo1b __attribute__((weak)); void * foo1b (void) { return (void *)&vfoo1b; } 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)); int vfoo1d; void * foo1d (void) { return (void *)&vfoo1d; } int vfoo1e; extern int vfoo1e __attribute__((weak)); void * foo1e (void) { return (void *)&vfoo1e; } int vfoo1f; void * foo1f (void) { return (void *)&vfoo1f; } extern int vfoo1f __attribute__((weak)); extern int vfoo1g; void * foo1g (void) { return (void *)&vfoo1g; } int vfoo1g __attribute__((weak)); extern int vfoo1h __attribute__((weak)); void * foo1h (void) { return (void *)&vfoo1h; } extern int vfoo1h __attribute__((weak)); int vfoo1h; extern int vfoo1i __attribute__((weak)); void * foo1i (void) { return (void *)&vfoo1i; } extern int vfoo1i __attribute__((weak)); extern int vfoo1i; extern int vfoo1j __attribute__((weak)); void * foo1j (void) { return (void *)&vfoo1j; } extern int vfoo1j; extern int vfoo1j __attribute__((weak)); extern int vfoo1k __attribute__((weak)); int vfoo1k = 1; int vfoox1l = 1; extern int vfoo1l __attribute__((alias ("vfoox1l"))); extern int vfoo1l __attribute__((weak, alias ("vfoox1l"))); --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-4.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-4.c" Content-length: 2385 /* { dg-do compile } */ /* { dg-options "-fno-common" } */ /* COFF does not support weak, and dg doesn't support UNSUPPORTED. */ /* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */ /* { dg-final { global target_triplet } } */ /* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */ /* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */ /* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */ /* test variable addresses with #pragma weak */ #pragma weak vfoo1a extern int vfoo1a; void * foo1a (void) { return (void *)&vfoo1a; } extern int vfoo1b; #pragma weak vfoo1b void * foo1b (void) { return (void *)&vfoo1b; } extern int vfoo1c; /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */ void * foo1c (void) { return (void *)&vfoo1c; } #pragma weak vfoo1c #pragma weak vfoo1d int vfoo1d; void * foo1d (void) { return (void *)&vfoo1d; } int vfoo1e; #pragma weak vfoo1e void * foo1e (void) { return (void *)&vfoo1e; } int vfoo1f; void * foo1f (void) { return (void *)&vfoo1f; } #pragma weak vfoo1f extern int vfoo1g; /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */ void * foo1g (void) { return (void *)&vfoo1g; } #pragma weak vfoo1g int vfoo1g; extern int vfoo1h; void * foo1h (void) { return (void *)&vfoo1h; } int vfoo1h; #pragma weak vfoo1h int vfoo1i; extern int vfoo1i; void * foo1i (void) { return (void *)&vfoo1i; } #pragma weak vfoo1i extern int vfoo1j; int vfoo1j; void * foo1j (void) { return (void *)&vfoo1j; } #pragma weak vfoo1j #pragma weak vfoo1k int vfoo1k = 1; --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-6.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-6.c" Content-length: 140 /* { dg-do compile } */ extern void * foo (void); void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */ #pragma weak foo --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J Content-Type: text/x-csrc; charset="iso-8859-1"; name="weak-7.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="weak-7.c" Content-length: 171 /* { dg-do compile } */ extern void * foo (void); void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */ extern void * foo (void) __attribute__((weak)); --------------Boundary-00=_FR8ABF2O2S7N0UDAY68J--