This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: #pragma weak is broken in 3.1, partail fix


The following is what I applied to 3.1.  It backports some of 
the visibility attribute changes from mainline that, as a side
effect, fixed some of the problems with weak aliases.  

Tested on alphaev6 and i386 linux.


r~


	2002-05-25  Richard Henderson  <rth@redhat.com>
	* c-pragma.c (apply_pragma_weak): Convert value identifier to 
	string for decl_attributes.
	(handle_pragma_weak): Call assemble_alias if we're modifying
	an existing decl.

	* gcc.dg/weak-9.c: New.

	2002-05-15  Richard Henderson  <rth@redhat.com>
	* varasm.c (merge_weak): Remove special case for extern and common.

	2002-05-15  Richard Henderson  <rth@redhat.com>
	* varasm.c (merge_weak): Error for any weakening after definition.
	Adjust weakening after use warning to catch more cases.
	(assemble_alias): Set TREE_USED and TREE_ASM_WRITTEN consistently.
	* config/alpha/alpha.c (alpha_encode_section_info): Do not abort.

	* gcc.dg/weak-5.c (vfoo1c): No warning here.
	(vfoo1f): Warning here.
	(vfoo1l): Don't redefine the alias.

	2002-03-02  Richard Henderson  <rth@redhat.com>
	* attribs.c (handle_alias_attribute): Don't call assemble_alias.
	* toplev.c (rest_of_decl_compilation): Invoke assemble_alias when
	needed.

Index: attribs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/attribs.c,v
retrieving revision 1.13
diff -c -p -d -r1.13 attribs.c
*** attribs.c	25 Feb 2002 22:38:52 -0000	1.13
--- attribs.c	27 May 2002 05:41:52 -0000
*************** handle_alias_attribute (node, name, args
*** 1050,1056 ****
  	DECL_INITIAL (decl) = error_mark_node;
        else
  	DECL_EXTERNAL (decl) = 0;
-       assemble_alias (decl, id);
      }
    else
      {
--- 1050,1055 ----
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.46.6.4
diff -c -p -d -r1.46.6.4 c-pragma.c
*** c-pragma.c	28 Apr 2002 18:43:53 -0000	1.46.6.4
--- c-pragma.c	27 May 2002 05:41:52 -0000
*************** apply_pragma_weak (decl, value)
*** 284,292 ****
       tree decl, value;
  {
    if (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 results in unspecified behavior");
--- 284,297 ----
       tree decl, value;
  {
    if (value)
!     {
!       value = build_string (IDENTIFIER_LENGTH (value),
! 			    IDENTIFIER_POINTER (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 results in unspecified behavior");
*************** handle_pragma_weak (dummy)
*** 343,349 ****
  
    decl = identifier_global_value (name);
    if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
!     apply_pragma_weak (decl, value);
    else
      pending_weaks = tree_cons (name, value, pending_weaks);
  }
--- 348,358 ----
  
    decl = identifier_global_value (name);
    if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
!     {
!       apply_pragma_weak (decl, value);
!       if (value)
! 	assemble_alias (decl, value);
!     }
    else
      pending_weaks = tree_cons (name, value, pending_weaks);
  }
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.574.2.15
diff -c -p -d -r1.574.2.15 toplev.c
*** toplev.c	23 May 2002 17:57:28 -0000	1.574.2.15
--- toplev.c	27 May 2002 05:41:53 -0000
*************** rest_of_decl_compilation (decl, asmspec,
*** 2248,2253 ****
--- 2248,2266 ----
  #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
  #endif
  
+   /* We deferred calling assemble_alias so that we could collect
+      other attributes such as visibility.  Emit the alias now.  */
+   {
+     tree alias;
+     alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+     if (alias)
+       {
+ 	alias = TREE_VALUE (TREE_VALUE (alias));
+ 	alias = get_identifier (TREE_STRING_POINTER (alias));
+         assemble_alias (decl, alias);
+       }
+   }
+ 
    /* Forward declarations for nested functions are not "external",
       but we need to treat them as if they were.  */
    if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.250.2.12
diff -c -p -d -r1.250.2.12 varasm.c
*** varasm.c	24 May 2002 19:22:08 -0000	1.250.2.12
--- varasm.c	27 May 2002 05:41:53 -0000
*************** merge_weak (newdecl, olddecl)
*** 5017,5030 ****
    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;
--- 5017,5022 ----
*************** merge_weak (newdecl, olddecl)
*** 5035,5044 ****
  	 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.
--- 5027,5043 ----
  	 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_ASM_WRITTEN (olddecl))
  	error_with_decl (newdecl, 
  			 "weak declaration of `%s' must precede definition");
! 
!       /* If we've already generated rtl referencing OLDDECL, we may
! 	 have done so in a way that will not function properly with
! 	 a weak symbol.  */
!       else if (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 (SUPPORTS_WEAK)
  	{
  	  /* We put the NEWDECL on the weak_decls list at some point.
*************** assemble_alias (decl, target)
*** 5175,5181 ****
  #else
    ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
  #endif
-   TREE_ASM_WRITTEN (decl) = 1;
  #else /* !ASM_OUTPUT_DEF */
  #if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
    if (! DECL_WEAK (decl))
--- 5174,5179 ----
*************** assemble_alias (decl, target)
*** 5186,5196 ****
  #else
    ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
  #endif
-   TREE_ASM_WRITTEN (decl) = 1;
  #else
    warning ("alias definitions not supported in this configuration; ignored");
  #endif
  #endif
  }
  
  /* Returns 1 if the target configuration supports defining public symbols
--- 5184,5197 ----
  #else
    ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
  #endif
  #else
    warning ("alias definitions not supported in this configuration; ignored");
  #endif
  #endif
+ 
+   TREE_USED (decl) = 1;
+   TREE_ASM_WRITTEN (decl) = 1;
+   TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
  }
  
  /* Returns 1 if the target configuration supports defining public symbols
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.233.2.9
diff -c -p -d -r1.233.2.9 alpha.c
*** config/alpha/alpha.c	10 Apr 2002 05:14:54 -0000	1.233.2.9
--- config/alpha/alpha.c	27 May 2002 05:41:53 -0000
*************** alpha_encode_section_info (decl)
*** 1664,1670 ****
        XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
      }
    else if (symbol_str[0] == '@')
!     abort ();
  }
  
  /* legitimate_address_p recognizes an RTL expression that is a valid
--- 1664,1674 ----
        XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
      }
    else if (symbol_str[0] == '@')
!     {
!       /* We're hosed.  This can happen when the user adds a weak
! 	 attribute after rtl generation.  They should have gotten
! 	 a warning about unspecified behaviour from varasm.c.  */
!     }
  }
  
  /* legitimate_address_p recognizes an RTL expression that is a valid
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.3
diff -c -p -d -r1.1.2.3 weak-5.c
*** testsuite/gcc.dg/weak-5.c	17 May 2002 04:04:29 -0000	1.1.2.3
--- testsuite/gcc.dg/weak-5.c	27 May 2002 05:41:53 -0000
***************
*** 9,26 ****
  /* { 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)) */
  
--- 9,26 ----
  /* { 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)) */
  
*************** void * foo1c (void)
*** 45,51 ****
  {
    return (void *)&vfoo1c;
  }
! extern int vfoo1c __attribute__((weak)); /* { dg-warning "weak declaration" "weak declaration" } */
  
  
  extern int vfoo1d __attribute__((weak));
--- 45,51 ----
  {
    return (void *)&vfoo1c;
  }
! extern int vfoo1c __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
  
  
  extern int vfoo1d __attribute__((weak));
*************** void * foo1f (void)
*** 69,75 ****
  {
    return (void *)&vfoo1f;
  }
! extern int vfoo1f __attribute__((weak));
  
  
  extern int vfoo1g;
--- 69,75 ----
  {
    return (void *)&vfoo1f;
  }
! extern int vfoo1f __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
  
  
  extern int vfoo1g;
*************** void * foo1g (void)
*** 77,83 ****
  {
    return (void *)&vfoo1g;
  }
! int vfoo1g __attribute__((weak));
  
  
  extern int vfoo1h __attribute__((weak));
--- 77,83 ----
  {
    return (void *)&vfoo1g;
  }
! int vfoo1g __attribute__((weak)); /* { dg-warning "unspecified behavior" } */
  
  
  extern int vfoo1h __attribute__((weak));
*************** int vfoo1k = 1;
*** 112,117 ****
  
  
  int vfoox1l = 1;
- extern int vfoo1l __attribute__((alias ("vfoox1l")));
  extern int vfoo1l __attribute__((weak, alias ("vfoox1l")));
- 
--- 112,115 ----
Index: testsuite/gcc.dg/weak-9.c
===================================================================
RCS file: testsuite/gcc.dg/weak-9.c
diff -N testsuite/gcc.dg/weak-9.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/weak-9.c	27 May 2002 05:41:53 -0000
***************
*** 0 ****
--- 1,28 ----
+ /* { 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\]_?f1" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f2" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f3" } } */
+ /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?f4" } } */
+ /* { dg-final { scan-assembler "notf1" } } */
+ /* { dg-final { scan-assembler "notf2" } } */
+ /* { dg-final { scan-assembler "notf3" } } */
+ /* { dg-final { scan-assembler "notf4" } } */
+ 
+ void f1() __attribute__((weak, alias("notf1")));
+ void f2() __attribute__((alias("notf2"), weak));
+ 
+ #pragma weak f3=notf3
+ void f3();
+ 
+ void f4();
+ #pragma weak f4=notf4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]