public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] missing return warnings
@ 2007-09-06  7:01 Jan Hubicka
  2007-09-06 10:03 ` Manuel López-Ibáñez
  2007-09-06 21:02 ` Mark Mitchell
  0 siblings, 2 replies; 7+ messages in thread
From: Jan Hubicka @ 2007-09-06  7:01 UTC (permalink / raw)
  To: gcc, mark

Hi,
I am looking into what parts of frontend stil depends on frontend inline
decision (ie DECL_INLINE now ignored by middle end).  All these uses
strike wrong, given that inlining decisions are independent on it.
These divergences for example requires us to enable expensive
-finline-functions for --profile-generate even though we really want it
only for --profile-use (where it is a lot cheaper given that profile
blocks unnecesary inlining).

For C++ there are number of cases I need to go through dealing with
attempts to not instantiate non-inline methods that won't be needed.
My plan is to make instantiation unconditional and measure effect on our
C++ benchmarks.
For C it seems to be single case for return warning:
/* PR c++/4872 */
/* { dg-do compile } */
/* { dg-options "-Wreturn-type" } */

static inline int f() {}     /* { dg-warning "return" "missing return" } */

In this case we produce missing return warning from frontend. 
This however is not truly consistent - if I make the function used, we
actually get two warnings - one from frontend, one from middle end
(that is CFG aware and does not merely check for presence of return
statement in  function).  If I remove the inline keyword, we lose the
warning since C frontend does not expect that we can now optimize out
static functions for a while.

The code in question is:

Index: c-decl.c
===================================================================
*** c-decl.c	(revision 128161)
--- c-decl.c	(working copy)
*************** finish_function (void)
*** 6752,6776 ****
  
    finish_fname_decls ();
  
-   /* Complain if there's just no return statement.  */
-   if (warn_return_type
-       && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
-       && !current_function_returns_value && !current_function_returns_null
-       /* Don't complain if we are no-return.  */
-       && !current_function_returns_abnormally
-       /* Don't warn for main().  */
-       && !MAIN_NAME_P (DECL_NAME (fndecl))
-       /* Or if they didn't actually specify a return type.  */
-       && !C_FUNCTION_IMPLICIT_INT (fndecl)
-       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
- 	 inline function, as we might never be compiled separately.  */
-       && DECL_INLINE (fndecl))
-     {
-       warning (OPT_Wreturn_type,
- 	       "no return statement in function returning non-void");
-       TREE_NO_WARNING (fndecl) = 1;
-     }
- 
    /* Store the end of the function, so that we get good line number
       info for the epilogue.  */
    cfun->function_end_locus = input_location;
--- 6725,6730 ----

I wonder what we want to do here - I guess we can either make the
warning unconditional and declare it as two indpendent things or we can
just drop the feature since user will get properly warned on every
function he actually uses.

What would be preferred solution here?

Similarly there is equivalent C++ frotned code.

Honza

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06  7:01 [RFC] missing return warnings Jan Hubicka
@ 2007-09-06 10:03 ` Manuel López-Ibáñez
  2007-09-06 21:02 ` Mark Mitchell
  1 sibling, 0 replies; 7+ messages in thread
From: Manuel López-Ibáñez @ 2007-09-06 10:03 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc, mark

On 06/09/07, Jan Hubicka <jh@suse.cz> wrote:
> I wonder what we want to do here - I guess we can either make the
> warning unconditional and declare it as two indpendent things or we can
> just drop the feature since user will get properly warned on every
> function he actually uses.
>
> What would be preferred solution here?

My preferred solution would be that TREE_NO_WARNING did actually
prevent to emit a duplicate warning.

tree-cfg.c (execute_warn_function_return)
------------------------------------------------------------------
 /* If we see "return;" in some basic block, then we do reach the end
     without returning a value.  */
  else if (warn_return_type
	   && !TREE_NO_WARNING (cfun->decl)
	   && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0
	   && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (cfun->decl))))
    {
      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
	{
	  tree last = last_stmt (e->src);
	  if (TREE_CODE (last) == RETURN_EXPR
	      && TREE_OPERAND (last, 0) == NULL
	      && !TREE_NO_WARNING (last))
	    {
#ifdef USE_MAPPED_LOCATION
	      location = EXPR_LOCATION (last);
	      if (location == UNKNOWN_LOCATION)
		  location = cfun->function_end_locus;
	      warning (0, "%Hcontrol reaches end of non-void function", &location);
#else
	      locus = EXPR_LOCUS (last);
	      if (!locus)
		locus = &cfun->function_end_locus;
	      warning (0, "%Hcontrol reaches end of non-void function", locus);
#endif
	      TREE_NO_WARNING (cfun->decl) = 1;
	      break;
	    }
	}
    }

Why is that not so? That would also prevent the whole loop  from being
executed at all. Do cfun->decl and fndecl point to different things?

If that is difficult then not getting a warning about a function that
is not used does not seem so tragic as long as the middle-end warns
for every case that the front-end would warn (assuming the function is
used). The warning in the middle-end does not depend on optimization
being enabled, does it?

Cheers,

Manuel.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06  7:01 [RFC] missing return warnings Jan Hubicka
  2007-09-06 10:03 ` Manuel López-Ibáñez
@ 2007-09-06 21:02 ` Mark Mitchell
  2007-09-06 22:50   ` Jan Hubicka
  1 sibling, 1 reply; 7+ messages in thread
From: Mark Mitchell @ 2007-09-06 21:02 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc

Jan Hubicka wrote:

> For C++ there are number of cases I need to go through dealing with
> attempts to not instantiate non-inline methods that won't be needed.

I'm not sure exactly what cases you're referring to, but please be
careful.  For example, changing if/when we instantiate template
functions, or if/when we generate bodies for implicitly defined
constructors, destructors, or assignment operators would be a semantic
change, and contrary to the standard.

> For C it seems to be single case for return warning:
> /* PR c++/4872 */
> /* { dg-do compile } */
> /* { dg-options "-Wreturn-type" } */
> 
> static inline int f() {}     /* { dg-warning "return" "missing return" } */
> 
> In this case we produce missing return warning from frontend. 
> This however is not truly consistent - if I make the function used, we
> actually get two warnings - one from frontend, one from middle end
> (that is CFG aware and does not merely check for presence of return
> statement in  function). 

As you know, I don't like the middle end issuing warnings at all.  So,
you'll not be surprised that I think we should warn about this function
independent of optimization.  People want these warnings to tell them
about possible bugs in their software, not just the ones that affect
them in their current configuration, depending on how much optimization
applies, etc.  If we want the middle end to warn about this kind of
case, we should make sure that it does so for all functions, used or not.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06 21:02 ` Mark Mitchell
@ 2007-09-06 22:50   ` Jan Hubicka
  2007-09-06 22:54     ` Mark Mitchell
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2007-09-06 22:50 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Jan Hubicka, gcc

> Jan Hubicka wrote:
> 
> > For C++ there are number of cases I need to go through dealing with
> > attempts to not instantiate non-inline methods that won't be needed.
> 
> I'm not sure exactly what cases you're referring to, but please be
> careful.  For example, changing if/when we instantiate template
> functions, or if/when we generate bodies for implicitly defined
> constructors, destructors, or assignment operators would be a semantic
> change, and contrary to the standard.

I am basically trying to avoid need for DECL_INLINE (while keeping
DECL_DECLARED_INLINE and DECL_UNINLINABLE for frontend use) - inliner is
now doing all the job himself to figure out what is or isn't needed.
There seems to be whole a lot of legacy code that is now wrong and/or
unnecesary (such as code preventing optimization of stack assignments on
inlinable functions to aid inliner or a lot of code assuming that only
inlinable functions are deferred).

We still should care about DECL_DECLARED_INLINE, if it affects semantics
of standard, but I would hope the output from frontends to actually not
depend on -finline-functions flag if possible.  I am experimenting with
the attached patch, it adds few failures:

With the noreturn warning made unconditional:
g++.dg/warn/pr23075.C (test for excess errors)                                                                                                              
g++.old-deja/g++.brendan/crash52.C (test for excess errors)                                                                                                 
g++.old-deja/g++.jason/report.C (test for excess errors)                                                                                                    
gcc.dg/20040206-1.c  (test for warnings, line 10)                                                                                                           
gcc.dg/20040206-1.c (test for excess errors)                                                                                                                
gcc.dg/pr23075.c  (test for warnings, line 14)                                                                                                              
gcc.dg/pr23075.c (test for excess errors)                                                                                                                   
gcc.dg/return-type-1.c (test for excess errors)                                                                                                             
gcc.dg/return-type-1.c warning for falling off end of non-void function
(test for warnings, line 9)                                                         
gcc.dg/return-type-3.c (test for excess errors)                                                                                                             
gcc.dg/return-type-3.c warning for falling off end of non-void function
(test for warnings, line 14)  

With the noreturn warning disabled completely:

g++.dg/warn/noreturn-2.C  (test for warnings, line 4)                                                                                                       
g++.old-deja/g++.bugs/900205_03.C  (test for errors, line 29)                                                                                               
g++.old-deja/g++.bugs/900205_03.C  (test for errors, line 32)                                                                                               
g++.old-deja/g++.law/operators17.C  (test for warnings, line 11)                                                                                            
gcc.dg/Wreturn-type.c (test for excess errors)                                                                                                              
gcc.dg/Wreturn-type.c missing return (test for warnings, line 5) 

So it seems to be all about those warnings now.

> 
> > For C it seems to be single case for return warning:
> > /* PR c++/4872 */
> > /* { dg-do compile } */
> > /* { dg-options "-Wreturn-type" } */
> > 
> > static inline int f() {}     /* { dg-warning "return" "missing return" } */
> > 
> > In this case we produce missing return warning from frontend. 
> > This however is not truly consistent - if I make the function used, we
> > actually get two warnings - one from frontend, one from middle end
> > (that is CFG aware and does not merely check for presence of return
> > statement in  function). 
> 
> As you know, I don't like the middle end issuing warnings at all.  So,
> you'll not be surprised that I think we should warn about this function
> independent of optimization.  People want these warnings to tell them
> about possible bugs in their software, not just the ones that affect
> them in their current configuration, depending on how much optimization
> applies, etc.  If we want the middle end to warn about this kind of
> case, we should make sure that it does so for all functions, used or not.

Yep, I agree that the warnings should generally come from frontends.
And in fact I was happy to move that warning before inliner to make it
more reliable with CFG inlining.  I also tend to think it is better to
make the simple frontend noreturn warning unconditional and the idea of
disabling later warning (that warns when some of paths to end of
function are not containing return statement) as good choice.

I am not sure it is feasible to trigger full lowering on every parsed
function up to level we are able to produce those warnings in generic
way.  It would mean we would want to do it for uninstantiated templates
for example.

Honza
> 
> -- 
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713


Index: java/class.c
===================================================================
*** java/class.c	(revision 128161)
--- java/class.c	(working copy)
*************** add_method_1 (tree this_class, int acces
*** 744,750 ****
    if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
    if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
    if (access_flags & ACC_PRIVATE)
!     METHOD_PRIVATE (fndecl) = DECL_INLINE (fndecl) = 1;
    if (access_flags & ACC_NATIVE)
      {
        METHOD_NATIVE (fndecl) = 1;
--- 744,750 ----
    if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
    if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
    if (access_flags & ACC_PRIVATE)
!     METHOD_PRIVATE (fndecl) = 1;
    if (access_flags & ACC_NATIVE)
      {
        METHOD_NATIVE (fndecl) = 1;
*************** add_method_1 (tree this_class, int acces
*** 755,763 ****
         file.  */
      DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
    if (access_flags & ACC_STATIC) 
!     METHOD_STATIC (fndecl) = DECL_INLINE (fndecl) = 1;
    if (access_flags & ACC_FINAL) 
!     METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1;
    if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
    if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
    if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
--- 755,763 ----
         file.  */
      DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
    if (access_flags & ACC_STATIC) 
!     METHOD_STATIC (fndecl) = 1;
    if (access_flags & ACC_FINAL) 
!     METHOD_FINAL (fndecl) = 1;
    if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
    if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
    if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
*************** make_local_function_alias (tree method)
*** 1334,1340 ****
    TREE_PUBLIC (alias) = 0;
    DECL_EXTERNAL (alias) = 0;
    DECL_ARTIFICIAL (alias) = 1;
-   DECL_INLINE (alias) = 0;
    DECL_INITIAL (alias) = error_mark_node;
    TREE_ADDRESSABLE (alias) = 1;
    TREE_USED (alias) = 1;
--- 1334,1339 ----
Index: java/expr.c
===================================================================
*** java/expr.c	(revision 128161)
--- java/expr.c	(working copy)
*************** rewrite_arglist_getcaller (tree arglist)
*** 2059,2066 ****
      = build_call_expr (built_in_decls[BUILT_IN_RETURN_ADDRESS],
  		       1, integer_zero_node);
    
-   DECL_INLINE (current_function_decl) = 0;
- 
    return chainon (arglist, 
  		  tree_cons (NULL_TREE, retaddr, 
  			     NULL_TREE));
--- 2059,2064 ----
Index: java/lang.c
===================================================================
*** java/lang.c	(revision 128161)
--- java/lang.c	(working copy)
*************** static bool
*** 897,903 ****
  java_decl_ok_for_sibcall (const_tree decl)
  {
    return (decl != NULL && DECL_CONTEXT (decl) == output_class
! 	  && DECL_INLINE (decl));
  }
  
  /* Given a call_expr, try to figure out what its target might be.  In
--- 897,903 ----
  java_decl_ok_for_sibcall (const_tree decl)
  {
    return (decl != NULL && DECL_CONTEXT (decl) == output_class
! 	  && DECL_DECLARED_INLINE_P (decl));
  }
  
  /* Given a call_expr, try to figure out what its target might be.  In
Index: cgraph.c
===================================================================
*** cgraph.c	(revision 128161)
--- cgraph.c	(working copy)
*************** cgraph_add_asm_node (tree asm_str)
*** 796,803 ****
  bool
  cgraph_function_possibly_inlined_p (tree decl)
  {
    if (!cgraph_global_info_ready)
!     return (DECL_INLINE (decl) && !flag_really_no_inline);
    return DECL_POSSIBLY_INLINED (decl);
  }
  
--- 796,807 ----
  bool
  cgraph_function_possibly_inlined_p (tree decl)
  {
+   if (DECL_UNINLINABLE (decl))
+     return false;
+   if (!flag_unit_at_a_time && !DECL_DECLARED_INLINE_P (decl))
+     return false;
    if (!cgraph_global_info_ready)
!     return !flag_really_no_inline;
    return DECL_POSSIBLY_INLINED (decl);
  }
  
Index: tree.h
===================================================================
*** tree.h	(revision 128161)
--- tree.h	(working copy)
*************** struct tree_decl_non_common GTY(())
*** 3269,3278 ****
  #define DECL_POSSIBLY_INLINED(DECL) \
    FUNCTION_DECL_CHECK (DECL)->function_decl.possibly_inlined
  
- /* Nonzero in a FUNCTION_DECL means this function can be substituted
-    where it is called.  */
- #define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.inline_flag)
- 
  /* Nonzero in a FUNCTION_DECL means that this function was declared inline,
     such as via the `inline' keyword in C/C++.  This flag controls the linkage
     semantics of 'inline'; whether or not the function is inlined is
--- 3269,3274 ----
Index: objc/objc-act.c
===================================================================
*** objc/objc-act.c	(revision 128161)
--- objc/objc-act.c	(working copy)
*************** objc_finish_method_definition (tree fnde
*** 8797,8803 ****
    /* We cannot validly inline ObjC methods, at least not without a language
       extension to declare that a method need not be dynamically
       dispatched, so suppress all thoughts of doing so.  */
-   DECL_INLINE (fndecl) = 0;
    DECL_UNINLINABLE (fndecl) = 1;
  
  #ifndef OBJCPLUS
--- 8797,8802 ----
Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 128161)
--- cgraphunit.c	(working copy)
*************** record_cdtor_fn (tree fndecl)
*** 196,202 ****
        static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
        DECL_STATIC_DESTRUCTOR (fndecl) = 0;
      }
-   DECL_INLINE (fndecl) = 1;
    node = cgraph_node (fndecl);
    node->local.disregard_inline_limits = 1;
    cgraph_mark_reachable_node (node);
--- 196,201 ----
*************** decide_is_function_needed (struct cgraph
*** 324,335 ****
    /* We want to emit COMDAT functions only when absolutely necessary.  */
    if (DECL_COMDAT (decl))
      return false;
!   if (!DECL_INLINE (decl)
!       || (!node->local.disregard_inline_limits
! 	  /* When declared inline, defer even the uninlinable functions.
! 	     This allows them to be eliminated when unused.  */
! 	  && !DECL_DECLARED_INLINE_P (decl)
! 	  && (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
      return true;
  
    return false;
--- 323,333 ----
    /* We want to emit COMDAT functions only when absolutely necessary.  */
    if (DECL_COMDAT (decl))
      return false;
!   if ((!node->local.disregard_inline_limits
! 	/* When declared inline, defer even the uninlinable functions.
! 	   This allows them to be eliminated when unused.  */
! 	&& !DECL_DECLARED_INLINE_P (decl)
! 	&& (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
      return true;
  
    return false;
*************** cgraph_preserve_function_body_p (tree de
*** 1253,1259 ****
    if (!cgraph_global_info_ready)
      return (flag_really_no_inline
  	    ? DECL_DISREGARD_INLINE_LIMITS (decl)
! 	    : DECL_INLINE (decl));
    /* Look if there is any clone around.  */
    for (node = cgraph_node (decl); node; node = node->next_clone)
      if (node->global.inlined_to)
--- 1251,1257 ----
    if (!cgraph_global_info_ready)
      return (flag_really_no_inline
  	    ? DECL_DISREGARD_INLINE_LIMITS (decl)
! 	    : DECL_DECLARED_INLINE_P (decl));
    /* Look if there is any clone around.  */
    for (node = cgraph_node (decl); node; node = node->next_clone)
      if (node->global.inlined_to)
Index: testsuite/gfortran.dg/do_3.F90
===================================================================
*** testsuite/gfortran.dg/do_3.F90	(revision 128161)
--- testsuite/gfortran.dg/do_3.F90	(working copy)
***************
*** 1,5 ****
  ! { dg-do run }
! ! { dg-options "-std=legacy -ffree-line-length-none -fno-range-check" }
  program test
    integer :: count
    integer :: i
--- 1,5 ----
  ! { dg-do run }
! ! { dg-options "-std=legacy -ffree-line-length-none -fno-range-check -fno-strict-overflow" }
  program test
    integer :: count
    integer :: i
Index: cp/typeck.c
===================================================================
*** cp/typeck.c	(revision 128161)
--- cp/typeck.c	(working copy)
*************** build_function_call (tree function, tree
*** 2696,2705 ****
  	 (because calling an inline function does not mean the function
  	 needs to be separately compiled).  */
  
!       if (DECL_INLINE (function))
! 	function = inline_conversion (function);
!       else
! 	function = build_addr_func (function);
      }
    else
      {
--- 2696,2702 ----
  	 (because calling an inline function does not mean the function
  	 needs to be separately compiled).  */
  
!       function = inline_conversion (function);
      }
    else
      {
Index: cp/optimize.c
===================================================================
*** cp/optimize.c	(revision 128161)
--- cp/optimize.c	(working copy)
*************** maybe_clone_body (tree fn)
*** 102,108 ****
  
        /* Update CLONE's source position information to match FN's.  */
        DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
-       DECL_INLINE (clone) = DECL_INLINE (fn);
        DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
        DECL_COMDAT (clone) = DECL_COMDAT (fn);
        DECL_WEAK (clone) = DECL_WEAK (fn);
--- 102,107 ----
Index: cp/decl.c
===================================================================
*** cp/decl.c	(revision 128161)
--- cp/decl.c	(working copy)
*************** duplicate_decls (tree newdecl, tree oldd
*** 1659,1670 ****
  	    {
  	      if (DECL_INITIAL (old_result))
  		{
- 		  DECL_INLINE (old_result) = 0;
  		  DECL_UNINLINABLE (old_result) = 1;
  		}
  	      else
  		{
- 		  DECL_INLINE (old_result) = DECL_INLINE (new_result);
  		  DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
  		}
  	      DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
--- 1659,1668 ----
*************** duplicate_decls (tree newdecl, tree oldd
*** 1677,1684 ****
  	    }
  	  else
  	    {
- 	      DECL_INLINE (old_result)
- 		|= DECL_INLINE (new_result);
  	      DECL_DECLARED_INLINE_P (old_result)
  		|= DECL_DECLARED_INLINE_P (new_result);
  	      check_redeclaration_exception_specification (newdecl, olddecl);
--- 1675,1680 ----
*************** duplicate_decls (tree newdecl, tree oldd
*** 1946,1952 ****
  	{
  	  /* C++ is always in in unit-at-a-time mode, so we never
  	     inline re-defined extern inline functions.  */
- 	  DECL_INLINE (newdecl) = 0;
  	  DECL_UNINLINABLE (newdecl) = 1;
  	}
        else
--- 1942,1947 ----
*************** duplicate_decls (tree newdecl, tree oldd
*** 1956,1967 ****
  
  	  DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
  
- 	  /* If either decl says `inline', this fn is inline, unless
- 	     its definition was passed already.  */
- 	  if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
- 	    DECL_INLINE (olddecl) = 1;
- 	  DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
- 
  	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
  	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
  
--- 1951,1956 ----
*************** start_cleanup_fn (void)
*** 5747,5753 ****
       actually needed.  It is unlikely that it will be inlined, since
       it is only called via a function pointer, but we avoid unnecessary
       emissions this way.  */
-   DECL_INLINE (fndecl) = 1;
    DECL_DECLARED_INLINE_P (fndecl) = 1;
    DECL_INTERFACE_KNOWN (fndecl) = 1;
    /* Build the parameter.  */
--- 5736,5741 ----
*************** grokfndecl (tree ctype,
*** 6417,6427 ****
    /* If the declaration was declared inline, mark it as such.  */
    if (inlinep)
      DECL_DECLARED_INLINE_P (decl) = 1;
-   /* We inline functions that are explicitly declared inline, or, when
-      the user explicitly asks us to, all functions.  */
-   if (DECL_DECLARED_INLINE_P (decl)
-       || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
-     DECL_INLINE (decl) = 1;
  
    DECL_EXTERNAL (decl) = 1;
    if (quals && TREE_CODE (type) == FUNCTION_TYPE)
--- 6405,6410 ----
*************** finish_function (int flags)
*** 11731,11739 ****
        /* Don't complain if we abort or throw.  */
        && !current_function_returns_abnormally
        && !DECL_NAME (DECL_RESULT (fndecl))
-       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
- 	 inline function, as we might never be compiled separately.  */
-       && (DECL_INLINE (fndecl) || processing_template_decl)
        /* Structor return values (if any) are set by the compiler.  */
        && !DECL_CONSTRUCTOR_P (fndecl)
        && !DECL_DESTRUCTOR_P (fndecl))
--- 11714,11719 ----
*************** start_method (cp_decl_specifier_seq *dec
*** 11847,11855 ****
  
    check_template_shadow (fndecl);
  
-   DECL_DECLARED_INLINE_P (fndecl) = 1;
    if (flag_default_inline)
!     DECL_INLINE (fndecl) = 1;
  
    /* We process method specializations in finish_struct_1.  */
    if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
--- 11827,11834 ----
  
    check_template_shadow (fndecl);
  
    if (flag_default_inline)
!     DECL_DECLARED_INLINE_P (fndecl) = 1;
  
    /* We process method specializations in finish_struct_1.  */
    if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
*************** cxx_push_function_context (struct functi
*** 12126,12136 ****
  	     now, restore saved state.  */
  	  *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
  
! 	  /* We don't need the saved data anymore.  Unless this is an inline
! 	     function; we need the named return value info for
! 	     declare_return_variable.  */
! 	  if (! DECL_INLINE (fn))
! 	    DECL_SAVED_FUNCTION_DATA (fn) = NULL;
  	}
      }
  }
--- 12105,12111 ----
  	     now, restore saved state.  */
  	  *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
  
! 	  DECL_SAVED_FUNCTION_DATA (fn) = NULL;
  	}
      }
  }
Index: cp/call.c
===================================================================
*** cp/call.c	(revision 128161)
--- cp/call.c	(working copy)
*************** build_over_call (struct z_candidate *can
*** 5138,5147 ****
  	fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
        TREE_TYPE (fn) = t;
      }
-   else if (DECL_INLINE (fn))
-     fn = inline_conversion (fn);
    else
!     fn = build_addr_func (fn);
  
    return build_cxx_call (fn, nargs, argarray);
  }
--- 5138,5145 ----
  	fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
        TREE_TYPE (fn) = t;
      }
    else
!     fn = inline_conversion (fn);
  
    return build_cxx_call (fn, nargs, argarray);
  }
Index: cp/method.c
===================================================================
*** cp/method.c	(revision 128161)
--- cp/method.c	(working copy)
*************** make_thunk (tree function, bool this_adj
*** 154,160 ****
    DECL_NO_STATIC_CHAIN (thunk) = 1;
    /* The THUNK is not a pending inline, even if the FUNCTION is.  */
    DECL_PENDING_INLINE_P (thunk) = 0;
-   DECL_INLINE (thunk) = 0;
    DECL_DECLARED_INLINE_P (thunk) = 0;
    /* Nor has it been deferred.  */
    DECL_DEFERRED_FN (thunk) = 0;
--- 154,159 ----
*************** make_alias_for (tree function, tree newi
*** 280,286 ****
    DECL_ARTIFICIAL (alias) = 1;
    DECL_NO_STATIC_CHAIN (alias) = 1;
    DECL_PENDING_INLINE_P (alias) = 0;
-   DECL_INLINE (alias) = 0;
    DECL_DECLARED_INLINE_P (alias) = 0;
    DECL_DEFERRED_FN (alias) = 0;
    DECL_USE_TEMPLATE (alias) = 0;
--- 279,284 ----
*************** implicitly_declare_fn (special_function_
*** 1107,1113 ****
    DECL_ARTIFICIAL (fn) = 1;
    DECL_NOT_REALLY_EXTERN (fn) = 1;
    DECL_DECLARED_INLINE_P (fn) = 1;
-   DECL_INLINE (fn) = 1;
    gcc_assert (!TREE_USED (fn));
  
    /* Restore PROCESSING_TEMPLATE_DECL.  */
--- 1105,1110 ----
Index: cp/pt.c
===================================================================
*** cp/pt.c	(revision 128161)
--- cp/pt.c	(working copy)
*************** register_specialization (tree spec, tree
*** 1270,1277 ****
  		{
  		  DECL_DECLARED_INLINE_P (clone)
  		    = DECL_DECLARED_INLINE_P (fn);
- 		  DECL_INLINE (clone)
- 		    = DECL_INLINE (fn);
  		}
  	      check_specialization_namespace (fn);
  
--- 1270,1275 ----
*************** regenerate_decl_from_template (tree decl
*** 14127,14134 ****
        if (DECL_DECLARED_INLINE_P (code_pattern)
  	  && !DECL_DECLARED_INLINE_P (decl))
  	DECL_DECLARED_INLINE_P (decl) = 1;
-       if (DECL_INLINE (code_pattern) && !DECL_INLINE (decl))
- 	DECL_INLINE (decl) = 1;
      }
    else if (TREE_CODE (decl) == VAR_DECL)
      DECL_INITIAL (decl) =
--- 14125,14130 ----
*************** instantiate_decl (tree d, int defer_ok,
*** 14352,14358 ****
    if (external_p
        /* ... but we instantiate inline functions so that we can inline
  	 them and ... */
!       && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
        /* ... we instantiate static data members whose values are
  	 needed in integral constant expressions.  */
        && ! (TREE_CODE (d) == VAR_DECL
--- 14348,14354 ----
    if (external_p
        /* ... but we instantiate inline functions so that we can inline
  	 them and ... */
!       && ! TREE_CODE (d) == FUNCTION_DECL
        /* ... we instantiate static data members whose values are
  	 needed in integral constant expressions.  */
        && ! (TREE_CODE (d) == VAR_DECL
*************** instantiate_decl (tree d, int defer_ok,
*** 14430,14436 ****
  	 job, even though we'll not be emitting a copy of this
  	 function.  */
        if (!(TREE_CODE (d) == FUNCTION_DECL
- 	    && flag_inline_trees
  	    && DECL_DECLARED_INLINE_P (d)))
  	goto out;
      }
--- 14426,14431 ----
Index: cp/semantics.c
===================================================================
*** cp/semantics.c	(revision 128161)
--- cp/semantics.c	(working copy)
*************** expand_body (tree fn)
*** 3141,3165 ****
  
    c_expand_body (fn);
  
-   if (DECL_CLONED_FUNCTION_P (fn))
-     {
-       /* If this is a clone, go through the other clones now and mark
- 	 their parameters used.  We have to do that here, as we don't
- 	 know whether any particular clone will be expanded, and
- 	 therefore cannot pick one arbitrarily.  */
-       tree probe;
- 
-       for (probe = TREE_CHAIN (DECL_CLONED_FUNCTION (fn));
- 	   probe && DECL_CLONED_FUNCTION_P (probe);
- 	   probe = TREE_CHAIN (probe))
- 	{
- 	  tree parms;
- 
- 	  for (parms = DECL_ARGUMENTS (probe);
- 	       parms; parms = TREE_CHAIN (parms))
- 	    TREE_USED (parms) = 1;
- 	}
-     }
  }
  
  /* Generate RTL for FN.  */
--- 3141,3146 ----
Index: cp/decl2.c
===================================================================
*** cp/decl2.c	(revision 128161)
--- cp/decl2.c	(working copy)
*************** start_static_storage_duration_function (
*** 2432,2438 ****
  			       type);
    TREE_PUBLIC (ssdf_decl) = 0;
    DECL_ARTIFICIAL (ssdf_decl) = 1;
-   DECL_INLINE (ssdf_decl) = 1;
  
    /* Put this function in the list of functions to be called from the
       static constructors and destructors.  */
--- 2432,2437 ----
*************** cp_write_global_declarations (void)
*** 3160,3166 ****
  	{
  	  /* Does it need synthesizing?  */
  	  if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
! 	      && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl)))
  	    {
  	      /* Even though we're already at the top-level, we push
  		 there again.  That way, when we pop back a few lines
--- 3159,3165 ----
  	{
  	  /* Does it need synthesizing?  */
  	  if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
! 	      && (! DECL_REALLY_EXTERN (decl)))
  	    {
  	      /* Even though we're already at the top-level, we push
  		 there again.  That way, when we pop back a few lines
*************** mark_used (tree decl)
*** 3508,3516 ****
    else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
  	   && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
  	   && (!DECL_EXPLICIT_INSTANTIATION (decl)
! 	       || (TREE_CODE (decl) == FUNCTION_DECL
! 		   && DECL_INLINE (DECL_TEMPLATE_RESULT
! 				   (template_for_substitution (decl))))
  	       /* We need to instantiate static data members so that there
  		  initializers are available in integral constant
  		  expressions.  */
--- 3507,3513 ----
    else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
  	   && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
  	   && (!DECL_EXPLICIT_INSTANTIATION (decl)
! 	       || TREE_CODE (decl) == FUNCTION_DECL
  	       /* We need to instantiate static data members so that there
  		  initializers are available in integral constant
  		  expressions.  */
Index: dojump.c
===================================================================
*** dojump.c	(revision 128161)
--- dojump.c	(working copy)
*************** clear_pending_stack_adjust (void)
*** 71,78 ****
  {
    if (optimize > 0
        && (! flag_omit_frame_pointer || current_function_calls_alloca)
!       && EXIT_IGNORE_STACK
!       && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline))
      discard_pending_stack_adjust ();
  }
  
--- 71,77 ----
  {
    if (optimize > 0
        && (! flag_omit_frame_pointer || current_function_calls_alloca)
!       && EXIT_IGNORE_STACK)
      discard_pending_stack_adjust ();
  }
  
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 128161)
--- ipa-inline.c	(working copy)
*************** cgraph_decide_inlining_incrementally (st
*** 1419,1435 ****
    return inlined;
  }
  
- /* When inlining shall be performed.  */
- static bool
- cgraph_gate_inlining (void)
- {
-   return flag_inline_trees;
- }
- 
  struct tree_opt_pass pass_ipa_inline = 
  {
    "inline",				/* name */
!   cgraph_gate_inlining,			/* gate */
    cgraph_decide_inlining,		/* execute */
    NULL,					/* sub */
    NULL,					/* next */
--- 1419,1428 ----
    return inlined;
  }
  
  struct tree_opt_pass pass_ipa_inline = 
  {
    "inline",				/* name */
!   NULL,					/* gate */
    cgraph_decide_inlining,		/* execute */
    NULL,					/* sub */
    NULL,					/* next */
*************** cgraph_early_inlining (void)
*** 1476,1482 ****
  static bool
  cgraph_gate_early_inlining (void)
  {
!   return flag_inline_trees && flag_early_inlining;
  }
  
  struct tree_opt_pass pass_early_inline = 
--- 1469,1475 ----
  static bool
  cgraph_gate_early_inlining (void)
  {
!   return flag_early_inlining;
  }
  
  struct tree_opt_pass pass_early_inline = 
*************** struct tree_opt_pass pass_early_inline =
*** 1500,1506 ****
  static bool
  cgraph_gate_ipa_early_inlining (void)
  {
!   return (flag_inline_trees && flag_early_inlining
  	  && (flag_branch_probabilities || flag_test_coverage
  	      || profile_arc_flag));
  }
--- 1493,1499 ----
  static bool
  cgraph_gate_ipa_early_inlining (void)
  {
!   return (flag_early_inlining
  	  && (flag_branch_probabilities || flag_test_coverage
  	      || profile_arc_flag));
  }
*************** compute_inline_parameters (void)
*** 1547,1563 ****
    return 0;
  }
  
- /* When inlining shall be performed.  */
- static bool
- gate_inline_passes (void)
- {
-   return flag_inline_trees;
- }
- 
  struct tree_opt_pass pass_inline_parameters = 
  {
    NULL,	 				/* name */
!   gate_inline_passes,			/* gate */
    compute_inline_parameters,		/* execute */
    NULL,					/* sub */
    NULL,					/* next */
--- 1540,1549 ----
    return 0;
  }
  
  struct tree_opt_pass pass_inline_parameters = 
  {
    NULL,	 				/* name */
!   NULL,					/* gate */
    compute_inline_parameters,		/* execute */
    NULL,					/* sub */
    NULL,					/* next */
Index: opts.c
===================================================================
*** opts.c	(revision 128161)
--- opts.c	(working copy)
*************** common_handle_option (size_t scode, cons
*** 1635,1642 ****
          flag_profile_values = value;
        if (!flag_value_profile_transformations_set)
          flag_value_profile_transformations = value;
-       if (!flag_inline_functions_set)
-         flag_inline_functions = value;
        break;
  
      case OPT_fprofile_values:
--- 1635,1640 ----
Index: ada/utils.c
===================================================================
*** ada/utils.c	(revision 128161)
--- ada/utils.c	(working copy)
*************** create_subprog_decl (tree subprog_name, 
*** 1859,1865 ****
    /* If this is a function nested inside an inlined external function, it
       means we aren't going to compile the outer function unless it is
       actually inlined, so do the same for us.  */
!   if (current_function_decl && DECL_INLINE (current_function_decl)
        && DECL_EXTERNAL (current_function_decl))
      extern_flag = true;
  
--- 1859,1865 ----
    /* If this is a function nested inside an inlined external function, it
       means we aren't going to compile the outer function unless it is
       actually inlined, so do the same for us.  */
!   if (current_function_decl && DECL_DECLARED_INLINE_P (current_function_decl)
        && DECL_EXTERNAL (current_function_decl))
      extern_flag = true;
  
*************** end_subprog_body (tree body)
*** 2106,2113 ****
  
    /* Deal with inline.  If declared inline or we should default to inline,
       set the flag in the decl.  */
!   DECL_INLINE (fndecl)
!     = DECL_DECLARED_INLINE_P (fndecl) || flag_inline_trees == 2;
  
    /* We handle pending sizes via the elaboration of types, so we don't
       need to save them.  */
--- 2106,2112 ----
  
    /* Deal with inline.  If declared inline or we should default to inline,
       set the flag in the decl.  */
!   DECL_DECLARED_INLINE_P (fndecl);
  
    /* We handle pending sizes via the elaboration of types, so we don't
       need to save them.  */
Index: c-decl.c
===================================================================
*** c-decl.c	(revision 128161)
--- c-decl.c	(working copy)
*************** merge_decls (tree newdecl, tree olddecl,
*** 1806,1812 ****
  	    (*debug_hooks->outlining_inline_function) (olddecl);
  
  	  /* The new defn must not be inline.  */
- 	  DECL_INLINE (newdecl) = 0;
  	  DECL_UNINLINABLE (newdecl) = 1;
  	}
        else
--- 1806,1811 ----
*************** merge_decls (tree newdecl, tree olddecl,
*** 1849,1870 ****
  	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (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)
! 		= 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;
  	}
      }
  
--- 1848,1855 ----
  	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
  	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
  
! 	  DECL_ABSTRACT_ORIGIN (newdecl)
! 	    = DECL_ABSTRACT_ORIGIN (olddecl);
  	}
      }
  
*************** grokdeclarator (const struct c_declarato
*** 4872,4890 ****
  	  {
  	    /* Record that the function is declared `inline'.  */
  	    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 -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;
        }
      else
        {
--- 4857,4863 ----
*************** finish_function (void)
*** 6761,6770 ****
        /* Don't warn for main().  */
        && !MAIN_NAME_P (DECL_NAME (fndecl))
        /* Or if they didn't actually specify a return type.  */
!       && !C_FUNCTION_IMPLICIT_INT (fndecl)
!       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
! 	 inline function, as we might never be compiled separately.  */
!       && DECL_INLINE (fndecl))
      {
        warning (OPT_Wreturn_type,
  	       "no return statement in function returning non-void");
--- 6734,6740 ----
        /* Don't warn for main().  */
        && !MAIN_NAME_P (DECL_NAME (fndecl))
        /* Or if they didn't actually specify a return type.  */
!       && !C_FUNCTION_IMPLICIT_INT (fndecl))
      {
        warning (OPT_Wreturn_type,
  	       "no return statement in function returning non-void");
Index: langhooks.c
===================================================================
*** langhooks.c	(revision 128161)
--- langhooks.c	(working copy)
*************** lhd_warn_unused_global_decl (const_tree 
*** 141,147 ****
    /* This is what used to exist in check_global_declarations.  Probably
       not many of these actually apply to non-C languages.  */
  
!   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
      return false;
    if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
      return false;
--- 141,147 ----
    /* This is what used to exist in check_global_declarations.  Probably
       not many of these actually apply to non-C languages.  */
  
!   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
      return false;
    if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
      return false;
Index: print-tree.c
===================================================================
*** print-tree.c	(revision 128161)
--- print-tree.c	(working copy)
*************** print_node (FILE *file, const char *pref
*** 365,372 ****
        if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
  	fputs (" suppress-debug", file);
  
!       if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
! 	fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
        if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
  	fputs (" built-in", file);
        if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
--- 365,372 ----
        if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
  	fputs (" suppress-debug", file);
  
!       if (TREE_CODE (node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (node))
! 	fputs ("inline", file);
        if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
  	fputs (" built-in", file);
        if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
*************** print_node (FILE *file, const char *pref
*** 450,456 ****
  	  print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4);
  	  
  	  if (TREE_CODE (node) != FUNCTION_DECL
! 	      || DECL_INLINE (node) || DECL_BUILT_IN (node))
  	    indent_to (file, indent + 3);
  	  
  	  if (DECL_USER_ALIGN (node))
--- 450,456 ----
  	  print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4);
  	  
  	  if (TREE_CODE (node) != FUNCTION_DECL
! 	      || DECL_DECLARED_INLINE_P (node) || DECL_BUILT_IN (node))
  	    indent_to (file, indent + 3);
  	  
  	  if (DECL_USER_ALIGN (node))
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 128161)
--- tree-inline.c	(working copy)
*************** inlinable_function_p (tree fn)
*** 1910,1916 ****
  
    /* We only warn for functions declared `inline' by the user.  */
    do_warning = (warn_inline
- 		&& DECL_INLINE (fn)
  		&& DECL_DECLARED_INLINE_P (fn)
  		&& !DECL_IN_SYSTEM_HEADER (fn));
  
--- 1910,1915 ----
*************** inlinable_function_p (tree fn)
*** 1960,1966 ****
       DECL_DECLARED_INLINE_P.  */
    /* FIXME: When flag_inline_trees dies, the check for flag_unit_at_a_time
  	    here should be redundant.  */
!   else if (!DECL_INLINE (fn) && !flag_unit_at_a_time)
      inlinable = false;
  
    else if (inline_forbidden_p (fn))
--- 1959,1965 ----
       DECL_DECLARED_INLINE_P.  */
    /* FIXME: When flag_inline_trees dies, the check for flag_unit_at_a_time
  	    here should be redundant.  */
!   else if (!DECL_DECLARED_INLINE_P (fn) && !flag_unit_at_a_time)
      inlinable = false;
  
    else if (inline_forbidden_p (fn))

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06 22:50   ` Jan Hubicka
@ 2007-09-06 22:54     ` Mark Mitchell
  2007-09-06 23:19       ` Jan Hubicka
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Mitchell @ 2007-09-06 22:54 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc

Jan Hubicka wrote:

> I am basically trying to avoid need for DECL_INLINE (while keeping
> DECL_DECLARED_INLINE and DECL_UNINLINABLE for frontend use) - inliner is
> now doing all the job himself to figure out what is or isn't needed.

That certainly makes sense to me.

> With the noreturn warning made unconditional:

...

> With the noreturn warning disabled completely:

...

> So it seems to be all about those warnings now.

OK, that sounds pretty encouraging.

Thansk,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06 22:54     ` Mark Mitchell
@ 2007-09-06 23:19       ` Jan Hubicka
  2007-09-07  1:06         ` Mark Mitchell
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2007-09-06 23:19 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Jan Hubicka, gcc

> Jan Hubicka wrote:
> 
> > I am basically trying to avoid need for DECL_INLINE (while keeping
> > DECL_DECLARED_INLINE and DECL_UNINLINABLE for frontend use) - inliner is
> > now doing all the job himself to figure out what is or isn't needed.
> 
> That certainly makes sense to me.
> 
> > With the noreturn warning made unconditional:
> 
> ...
> 
> > With the noreturn warning disabled completely:
> 
> ...
> 
> > So it seems to be all about those warnings now.
> 
> OK, that sounds pretty encouraging.

One problem that I am concerned about is that C++ frontend is actually
trying to avoid instantiating some stuff that it knows will not be
needed if not inlined.  I would kill this logic, but I hope this is the
case where the feature is not worth the maintenance cost.

I've applied the patch for C++ nightly testing, for tramp3d, the
difference seems to be in wash.  I will do some proofreading tomorrow
and send updated patch.

Honza
> 
> Thansk,
> 
> -- 
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] missing return warnings
  2007-09-06 23:19       ` Jan Hubicka
@ 2007-09-07  1:06         ` Mark Mitchell
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Mitchell @ 2007-09-07  1:06 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Jan Hubicka, gcc

Jan Hubicka wrote:

> One problem that I am concerned about is that C++ frontend is actually
> trying to avoid instantiating some stuff that it knows will not be
> needed if not inlined.  I would kill this logic, but I hope this is the
> case where the feature is not worth the maintenance cost.

We need to be careful about terms.  "Instantiating" means "substituting
actual arguments into a template definition to get an actual
definition".  There's also generating definitions for
implicitly-declared class member functions; that doesn't have a great
term in the standard, but we can call it "defining implicit functions".
 Which one of these situations are you concerned about?

I guess, in a way, it doesn't matter which one.  In both cases, the
standard says when you must do it.  So, we can't change that.

I suspect that the code that you're looking at may have just been a
front-end optimization.  For example, at least at one point, it made GCC
a lot slower to have very long instantiation chains: f needs g<int>,
g<int> needs h<int>, etc.  It was better to instantiate things one at a
time than to have a deep stack.  But, if h<int> was inline, then we
needed to make sure its body was available when g<int> was being
instantiated so that we could inline it.  Now, that's probably no longer
true.  We can probably always avoid the deep stack, and just let cgraph
handle it.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-09-07  1:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-06  7:01 [RFC] missing return warnings Jan Hubicka
2007-09-06 10:03 ` Manuel López-Ibáñez
2007-09-06 21:02 ` Mark Mitchell
2007-09-06 22:50   ` Jan Hubicka
2007-09-06 22:54     ` Mark Mitchell
2007-09-06 23:19       ` Jan Hubicka
2007-09-07  1:06         ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).