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]

C++ PATCH to warn about inlines which fail to return a value


There have been various complaints over the years about g++ failing to
catch the case where control flows off the end of an inline function;
-Wreturn-type doesn't work because we don't compile the function
separately.  This is hard in general, but we can certainly catch the most
common, trivial case, that of the function lacking any return statement
whatsoever.

I think this is an obvious enough mistake that it's worth an unconditional
warning; I've softened it somewhat by suppressing the warning if there's a
call to a noreturn function (including __cxa_throw).  However, if people
feel strongly that it should only be active with -Wreturn-type, I'm open to
that.

Tested i686-pc-linux-gnu.  Many existing tests.  Regression from 2.95.

2002-02-01  Jason Merrill  <jason@redhat.com>

	PR c++/4872
	* decl.c (finish_function): Warn about a non-void function with 
	no return statement and no abnormal exit.
	* cp-tree.h (struct cp_language_function): Add returns_abnormally.
	(current_function_returns_abnormally): New macro.
	* call.c (build_call): Set it.

*** decl.c.~1~	Fri Feb  1 18:51:32 2002
--- decl.c	Fri Feb  1 18:56:30 2002
*************** finish_function (flags)
*** 14247,14252 ****
--- 14247,14264 ----
    if (!processing_template_decl && calls_setjmp_p (fndecl))
      DECL_UNINLINABLE (fndecl) = 1;
  
+   /* Complain if there's just no return statement.  */
+   if (!processing_template_decl
+       && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
+       && !current_function_returns_value
+       && !DECL_NAME (DECL_RESULT (fndecl))
+       /* Don't complain if we abort or throw.  */
+       && !current_function_returns_abnormally
+       /* If we have -Wreturn-type, let flow complain.  Unless we're an
+ 	 inline function, as we might never be compiled separately.  */
+       && (!warn_return_type || DECL_INLINE (fndecl))
+     warning ("no return statement in function returning non-void");
+     
    /* Clear out memory we no longer need.  */
    free_after_parsing (cfun);
    /* Since we never call rest_of_compilation, we never clear
*** cp-tree.h.~1~	Fri Feb  1 18:51:32 2002
--- cp-tree.h	Fri Feb  1 15:57:34 2002
*************** struct cp_language_function
*** 821,826 ****
--- 821,827 ----
  
    int returns_value;
    int returns_null;
+   int returns_abnormally;
    int in_function_try_handler;
    int x_expanding_p;
  
*************** struct cp_language_function
*** 883,888 ****
--- 884,895 ----
  
  #define current_function_returns_null cp_function_chain->returns_null
  
+ /* Set to 0 at beginning of a function definition, set to 1 if
+    a call to a noreturn function is seen.  */
+ 
+ #define current_function_returns_abnormally \
+   cp_function_chain->returns_abnormally
+ 
  /* Non-zero if we should generate RTL for functions that we process.
     When this is zero, we just accumulate tree structure, without
     interacting with the back end.  */
*** call.c.~1~	Fri Feb  1 18:51:32 2002
--- call.c	Fri Feb  1 16:02:35 2002
*************** build_call (function, parms)
*** 408,413 ****
--- 408,416 ----
    nothrow = ((decl && TREE_NOTHROW (decl))
  	     || TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
  
+   if (decl && TREE_THIS_VOLATILE (decl))
+     current_function_returns_abnormally = 1;
+ 
    if (decl && TREE_DEPRECATED (decl))
      warn_deprecated_use (decl);
  

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