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: [RFC] missing return warnings


> 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))


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