This is the mail archive of the gcc-bugs@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: target/6569: sparc-sun-solaris2.7 C testsuite regression incompile/20011119-2.c




--On Tuesday, May 07, 2002 07:24:48 PM +0200 Franz Sirl 
<Franz.Sirl-kernel@lauterbach.com> wrote:

Don't worry; we'll get it fixed.

The problem is that there are multiple declarations of functions involved.

If you say:

  void f()
  void f() __attribute__((weak));

The C front end makes two DECLs for f.  Then, it calls duplicate_decls to
smush them together; it always throws away the new one and keeps the old.
We're getting the new one on the weak_decls list sometimes, and that's
messing things up.

This patch will fix it; I'm testing on x86 now, and if someone can
kick off a SPARC run that would be great.  As a special bonus, this
also makes the warnings come out in the right place consistently.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.co

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	7 May 2002 18:18:46 -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]