This is the mail archive of the gcc-patches@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: [PATCH] Fix PR c/5163


On Fri, Dec 21, 2001 at 11:43:57PM +0100, Jakub Jelinek wrote:
> (or why is actually a DECL_EXTERNAL ever marked DECL_INLINE).

This, I think, is the root of the problem.  I've applied
the following patch.


r~


	PR c/5163:
	* c-decl.c (duplicate_decls): As needed, set DECL_INLINE when
	we have a function body associated.  Minor cleanups.
	(grokdeclarator): Do not set DECL_INLINE without a function body.

	* gcc.dg/20011223-1.c: New.
	* gcc.dg/inline-1.c: New.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.284
diff -c -p -d -r1.284 c-decl.c
*** c-decl.c	2001/12/17 01:18:39	1.284
--- c-decl.c	2001/12/24 07:25:03
*************** duplicate_decls (newdecl, olddecl, diffe
*** 1974,1983 ****
  	  /* If either decl says `inline', this fn is inline,
  	     unless its definition was passed already.  */
  	  if (DECL_DECLARED_INLINE_P (newdecl)
! 	      && DECL_DECLARED_INLINE_P (olddecl) == 0)
! 	    DECL_DECLARED_INLINE_P (olddecl) = 1;
! 
! 	  DECL_DECLARED_INLINE_P (newdecl) = DECL_DECLARED_INLINE_P (olddecl);
  
  	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
  	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
--- 1974,1981 ----
  	  /* If either decl says `inline', this fn is inline,
  	     unless its definition was passed already.  */
  	  if (DECL_DECLARED_INLINE_P (newdecl)
! 	      || DECL_DECLARED_INLINE_P (olddecl))
! 	    DECL_DECLARED_INLINE_P (newdecl) = 1;
  
  	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
  	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
*************** duplicate_decls (newdecl, olddecl, diffe
*** 2003,2011 ****
  	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
  	    }
  	}
        /* Also preserve various other info from the definition.  */
-       else if (! new_is_definition)
- 	DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
        if (! new_is_definition)
  	{
  	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
--- 2001,2008 ----
  	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
  	    }
  	}
+ 
        /* Also preserve various other info from the definition.  */
        if (! new_is_definition)
  	{
  	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
*************** duplicate_decls (newdecl, olddecl, diffe
*** 2016,2027 ****
  	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
  	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
  	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
  	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
! 	  if (DECL_INLINE (newdecl))
! 	    DECL_ABSTRACT_ORIGIN (newdecl)
! 	      = (different_binding_level
! 		 ? DECL_ORIGIN (olddecl)
! 		 : DECL_ABSTRACT_ORIGIN (olddecl));
  	}
      }
    if (different_binding_level)
--- 2013,2039 ----
  	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
  	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
  	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ 	  DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
  	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
! 
! 	  /* Set DECL_INLINE on the declaration if we've got a body
! 	     from which to instantiate.  */
! 	  if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
! 	    {
! 	      DECL_INLINE (newdecl) = 1;
! 	      DECL_ABSTRACT_ORIGIN (newdecl)
! 		= (different_binding_level
! 		   ? DECL_ORIGIN (olddecl)
! 		   : DECL_ABSTRACT_ORIGIN (olddecl));
! 	    }
! 	}
!       else
! 	{
! 	  /* If a previous declaration said inline, mark the
! 	     definition as inlinable.  */
! 	  if (DECL_DECLARED_INLINE_P (newdecl)
! 	      && ! DECL_UNINLINABLE (newdecl))
! 	    DECL_INLINE (newdecl) = 1;
  	}
      }
    if (different_binding_level)
*************** grokdeclarator (declarator, declspecs, d
*** 5049,5064 ****
  	else if (inlinep)
  	  {
  	    /* Assume that otherwise the function can be inlined.  */
- 	    DECL_INLINE (decl) = 1;
  	    DECL_DECLARED_INLINE_P (decl) = 1;
  
! 	    if (specbits & (1 << (int) RID_EXTERN))
! 	      current_extern_inline = 1;
  	  }
  	/* If -finline-functions, assume it can be inlined.  This does
  	   two things: let the function be deferred until it is actually
  	   needed, and let dwarf2 know that the function is inlinable.  */
! 	else if (flag_inline_trees == 2)
  	  {
  	    DECL_INLINE (decl) = 1;
  	    DECL_DECLARED_INLINE_P (decl) = 0;
--- 5061,5083 ----
  	else if (inlinep)
  	  {
  	    /* Assume that otherwise the function can be inlined.  */
  	    DECL_DECLARED_INLINE_P (decl) = 1;
  
! 	    /* Do not mark bare declarations as DECL_INLINE.  Doing so
! 	       in the presence of multiple declarations can result in
! 	       the abstract origin pointing between the declarations,
! 	       which will confuse dwarf2out.  */
! 	    if (initialized)
! 	      {
! 		DECL_INLINE (decl) = 1;
! 		if (specbits & (1 << (int) RID_EXTERN))
! 		  current_extern_inline = 1;
! 	      }
  	  }
  	/* If -finline-functions, assume it can be inlined.  This does
  	   two things: let the function be deferred until it is actually
  	   needed, and let dwarf2 know that the function is inlinable.  */
! 	else if (flag_inline_trees == 2 && initialized)
  	  {
  	    DECL_INLINE (decl) = 1;
  	    DECL_DECLARED_INLINE_P (decl) = 0;
Index: testsuite/gcc.dg/20011223-1.c
===================================================================
RCS file: 20011223-1.c
diff -N 20011223-1.c
*** /dev/null	Tue May  5 13:32:27 1998
--- 20011223-1.c	Sun Dec 23 23:25:03 2001
***************
*** 0 ****
--- 1,12 ----
+ /* Origin: PR c/5163 from aj@suse.de.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O3 -g" } */
+ 
+ extern int bar (int);
+ 
+ int
+ foo (void)
+ {
+   extern int bar (int);
+   return bar (5);
+ }
Index: testsuite/gcc.dg/inline-1.c
===================================================================
RCS file: inline-1.c
diff -N inline-1.c
*** /dev/null	Tue May  5 13:32:27 1998
--- inline-1.c	Sun Dec 23 23:25:03 2001
***************
*** 0 ****
--- 1,28 ----
+ /* Verify that DECL_INLINE gets copied between DECLs properly.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O1" } */
+ /* { dg-final { scan-assembler-not "xyzzy" } } */
+ 
+ /* Test that declaration followed by definition inlines.  */
+ static inline int xyzzy0 (int);
+ static int xyzzy0 (int x) { return x; }
+ int test0 (void)
+ {
+   return xyzzy0 (5);
+ }
+ 
+ /* Test that definition following declaration inlines.  */
+ static int xyzzy1 (int);
+ static inline int xyzzy1 (int x) { return x; }
+ int test1 (void)
+ {
+   return xyzzy1 (5);
+ }
+ 
+ /* Test that redeclaration inside a function body inlines.  */
+ extern inline int xyzzy2 (int x) { return x; }
+ int test2 (void)
+ {
+   extern int xyzzy2 (int);
+   return xyzzy2 (5);
+ }


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