re PR c++/54046 (wrong control reaches end of non-void function for switch case with...
authorJakub Jelinek <jakub@redhat.com>
Fri, 23 Nov 2012 16:04:03 +0000 (17:04 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 23 Nov 2012 16:04:03 +0000 (17:04 +0100)
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.

From-SVN: r193762

gcc/ChangeLog
gcc/Makefile.in
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.c
gcc/cp/cp-objcp-common.h
gcc/cp/cp-tree.h
gcc/gimple-low.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wreturn-type-8.C [new file with mode: 0644]

index 46760a06e4a3df3dfb40c73541ae857357797d01..ee7531ce40de9bc650c99d5d217d269965120865 100644 (file)
@@ -1,3 +1,15 @@
+2012-11-23  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.
+
 2012-11-23  Jan Hubicka  <jh@suse.cz>
 
        * i386-c.c (ix86_target_macros_internal): Update handling of core
index 7ac7b2594a215b018217d9c32baf85f220d79b00..44f1e0858661f8b5c1ae7d702fec466ab1346902 100644 (file)
@@ -2527,7 +2527,7 @@ gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_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) \
index 47734c58d43029dcf83dc39d792d5ee69f980729..95fb0bff8641a35f9a8e723a040308b57012c66b 100644 (file)
@@ -1,3 +1,10 @@
+2012-11-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/54046
+       * 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.
+
 2012-11-23  Markus Trippelsdorf  <markus@trippelsdorf.de>
 
        PR c++/55418
index 9b7d361939cba44856155114c4ea1edbd3bfcd01..20dd33950374d58945e99a29abd577669f3deacc 100644 (file)
@@ -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 false;
+
+    default:
+      return true;
+    }
+}
+
 void
 cp_common_init_ts (void)
 {
index 06cc796050b6f6aadfbb3c067872a0cf1cf9e2b1..4cfc59c40d209668f9aef9a0c86248a3efbec5e6 100644 (file)
@@ -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
index 8592125e4cf76231d7b1181815bfa66d6ea46ac5..85c8e7c702cce3138b54d08c625d9f356edc1826 100644 (file)
@@ -6019,6 +6019,7 @@ extern bool cp_var_mod_type_p                     (tree, tree);
 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 *,
index e26d91ef4b4bb131568760225e6e92aa8e22e257..282dba187c3eb3dfaf713a55dc1f0bc60962d972 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #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);
     }
 }
 
index d8f479f3f5dc0c291d4656d28ba904a0a3e992e0..75793f623255fb6de933b21f7a73d025e160558f 100644 (file)
@@ -115,6 +115,7 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
 #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 \
 }
index a91906729204cc0033c0f2c8adcfb6197c78989a..8481ba46d6cbbbf980e4b8ab680f1a00a4602aa4 100644 (file)
@@ -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;
index ee90eeb74bde6fdf43415ae2bfdb845f048e96c8..a42b0013393c8713cf0b1ccb5ceb2cfa3684287a 100644 (file)
@@ -1,5 +1,8 @@
 2012-11-23  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/54046
+       * g++.dg/warn/Wreturn-type-8.C: New test.
+
        PR middle-end/55430
        * gcc.dg/pr55430.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-type-8.C b/gcc/testsuite/g++.dg/warn/Wreturn-type-8.C
new file mode 100644 (file)
index 0000000..346cab4
--- /dev/null
@@ -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 ();
+    }
+}