Patchwork Avoid some further -Wreturn-type false positives (PR c++/54046)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 20, 2012, 8:31 p.m.
Message ID <20121120203140.GW2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/200512/
State New
Headers show

Comments

Jakub Jelinek - Nov. 20, 2012, 8:31 p.m.
Hi!

This is an attempt to avoid some further -Wreturn-type false positives,
by adding a langhook for block_may_fallthru and thus allowing it to handle
selected FE specific trees (like EXPR_STMT or THROW_EXPR) and handling also
TARGET_EXPR.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2012-11-20  Jakub Jelinek  <jakub@redhat.com>

	PR c++/54046
	* Makefile.in (gimple-low.o): Depend on langhooks.h.
	* gimple-low.c: Include langhooks.c.
	(block_may_fallthru): Handle TARGET_EXPR and ERROR_MARK,
	by default call lang_hooks.block_may_fallthru.
	* langhooks.h (struct lang_hooks): Add block_may_fallthru
	langhook.
	* langhooks-def.h (LANG_HOOKS_BLOCK_MAY_FALLTHRU): Define.
	(LANG_HOOKS_INITIALIZER): Use it.

	* cp-objcp-common.h (LANG_HOOKS_BLOCK_MAY_FALLTHRU): Redefine.
	* cp-objcp-common.c (cxx_block_may_fallthru): New function.
	* cp-tree.h (cxx_block_may_fallthru): New prototype.

	* g++.dg/warn/Wreturn-type-8.C: New test.


	Jakub
Jason Merrill - Nov. 23, 2012, 3:45 p.m.
On 11/20/2012 03:31 PM, Jakub Jelinek wrote:
> +    case THROW_EXPR:
> +      return block_may_fallthru (TREE_OPERAND (stmt, 0));

Shouldn't this just be false?  OK with that change.

Jason

Patch

--- gcc/Makefile.in.jj	2012-11-20 11:36:51.000000000 +0100
+++ gcc/Makefile.in	2012-11-20 17:28:58.601741316 +0100
@@ -2519,7 +2519,7 @@  gimple-low.o : gimple-low.c $(CONFIG_H)
    $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TM_H) coretypes.h \
    $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(TREE_PASS_H) \
-   $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) tree-iterator.h
+   $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) tree-iterator.h langhooks.h
 omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \
    $(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \
--- gcc/gimple-low.c.jj	2012-11-19 14:41:18.000000000 +0100
+++ gcc/gimple-low.c	2012-11-20 17:28:33.518881995 +0100
@@ -32,6 +32,7 @@  along with GCC; see the file COPYING3.
 #include "function.h"
 #include "diagnostic-core.h"
 #include "tree-pass.h"
+#include "langhooks.h"
 
 /* The differences between High GIMPLE and Low GIMPLE are the
    following:
@@ -739,8 +740,14 @@  block_may_fallthru (const_tree block)
     case CLEANUP_POINT_EXPR:
       return block_may_fallthru (TREE_OPERAND (stmt, 0));
 
-    default:
+    case TARGET_EXPR:
+      return block_may_fallthru (TREE_OPERAND (stmt, 1));
+
+    case ERROR_MARK:
       return true;
+
+    default:
+      return lang_hooks.block_may_fallthru (stmt);
     }
 }
 
--- gcc/langhooks.h.jj	2012-07-16 14:38:34.000000000 +0200
+++ gcc/langhooks.h	2012-11-20 17:25:07.019061084 +0100
@@ -1,6 +1,6 @@ 
 /* The lang_hooks data structure.
    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   2011, 2012 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -456,6 +456,10 @@  struct lang_hooks
      FUNCTION_DECL for `std::terminate'.  */
   tree (*eh_protect_cleanup_actions) (void);
 
+  /* Return true if a stmt can fallthru.  Used by block_may_fallthru
+     to possibly handle language trees.  */
+  bool (*block_may_fallthru) (const_tree);
+
   /* True if this language uses __cxa_end_cleanup when the ARM EABI
      is enabled.  */
   bool eh_use_cxa_end_cleanup;
--- gcc/langhooks-def.h.jj	2012-04-30 08:06:18.000000000 +0200
+++ gcc/langhooks-def.h	2012-11-20 17:26:15.616672118 +0100
@@ -115,6 +115,7 @@  extern void lhd_omp_firstprivatize_type_
 #define LANG_HOOKS_EH_PERSONALITY	lhd_gcc_personality
 #define LANG_HOOKS_EH_RUNTIME_TYPE	lhd_pass_through_t
 #define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS	NULL
+#define LANG_HOOKS_BLOCK_MAY_FALLTHRU	hook_bool_const_tree_true
 #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP	false
 #define LANG_HOOKS_DEEP_UNSHARING	false
 
@@ -300,6 +301,7 @@  extern void lhd_end_section (void);
   LANG_HOOKS_EH_PERSONALITY, \
   LANG_HOOKS_EH_RUNTIME_TYPE, \
   LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \
+  LANG_HOOKS_BLOCK_MAY_FALLTHRU, \
   LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \
   LANG_HOOKS_DEEP_UNSHARING \
 }
--- gcc/cp/cp-objcp-common.h.jj	2012-04-23 11:11:19.000000000 +0200
+++ gcc/cp/cp-objcp-common.h	2012-11-20 17:30:18.637283695 +0100
@@ -94,6 +94,8 @@  extern void cp_common_init_ts (void);
 #define LANG_HOOKS_TYPE_HASH_EQ	cxx_type_hash_eq
 #undef LANG_HOOKS_MISSING_NORETURN_OK_P
 #define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p
+#undef LANG_HOOKS_BLOCK_MAY_FALLTHRU
+#define LANG_HOOKS_BLOCK_MAY_FALLTHRU cxx_block_may_fallthru
 
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
--- gcc/cp/cp-tree.h.jj	2012-11-19 14:41:16.000000000 +0100
+++ gcc/cp/cp-tree.h	2012-11-20 17:33:43.470104218 +0100
@@ -6019,6 +6019,7 @@  extern bool cp_var_mod_type_p			(tree, t
 extern void cxx_initialize_diagnostics		(diagnostic_context *);
 extern int cxx_types_compatible_p		(tree, tree);
 extern void init_shadowed_var_for_decl		(void);
+extern bool cxx_block_may_fallthru		(const_tree);
 
 /* in cp-gimplify.c */
 extern int cp_gimplify_expr			(tree *, gimple_seq *,
--- gcc/cp/cp-objcp-common.c.jj	2012-05-17 08:40:35.000000000 +0200
+++ gcc/cp/cp-objcp-common.c	2012-11-20 17:40:40.147732468 +0100
@@ -227,6 +227,25 @@  init_shadowed_var_for_decl (void)
 					   tree_decl_map_eq, 0);
 }
 
+/* Return true if stmt can fall thru.  Used by block_may_fallthru
+   default case.  */
+
+bool
+cxx_block_may_fallthru (const_tree stmt)
+{
+  switch (TREE_CODE (stmt))
+    {
+    case EXPR_STMT:
+      return block_may_fallthru (EXPR_STMT_EXPR (stmt));
+
+    case THROW_EXPR:
+      return block_may_fallthru (TREE_OPERAND (stmt, 0));
+
+    default:
+      return true;
+    }
+}
+
 void
 cp_common_init_ts (void)
 {
--- gcc/testsuite/g++.dg/warn/Wreturn-type-8.C.jj	2012-11-20 17:46:30.899731596 +0100
+++ gcc/testsuite/g++.dg/warn/Wreturn-type-8.C	2012-11-20 17:45:22.000000000 +0100
@@ -0,0 +1,90 @@ 
+// PR c++/54046
+// { dg-do compile }
+// { dg-options "-O0 -Wall" }
+
+void foo (void) __attribute__((noreturn));
+
+struct A
+{
+  ~A () {}
+};
+
+bool
+check1 (int x)
+{
+  A z;
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      throw "X";
+      break;
+    }
+}
+
+bool
+check2 (int x)
+{
+  A z;
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      foo ();
+      break;
+    }
+}
+
+bool
+check3 (int x)
+{
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      throw "X";
+      break;
+    }
+}
+
+bool
+check4 (int x)
+{
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      foo ();
+      break;
+    }
+}
+
+bool
+check5 (int x)
+{
+  A z;
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      throw "X";
+    }
+}
+
+bool
+check6 (int x)
+{
+  A z;
+  switch (x)
+    {
+    case 0:
+      return false;
+    default:
+      foo ();
+    }
+}