Comments
Patch
===================================================================
@@ -79,6 +79,8 @@ extern tree lhd_omp_assignment (tree, tr
struct gimplify_omp_ctx;
extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
tree);
+extern bool lhd_tree_may_fallthru (const_tree);
+
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
@@ -118,6 +120,7 @@ extern void lhd_omp_firstprivatize_type_
#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS NULL
#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false
#define LANG_HOOKS_DEEP_UNSHARING false
+#define LANG_HOOKS_TREE_MAY_FALLTHRU lhd_tree_may_fallthru
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
@@ -309,7 +312,8 @@ extern void lhd_end_section (void);
LANG_HOOKS_EH_RUNTIME_TYPE, \
LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \
LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \
- LANG_HOOKS_DEEP_UNSHARING \
+ LANG_HOOKS_DEEP_UNSHARING, \
+ LANG_HOOKS_TREE_MAY_FALLTHRU \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
===================================================================
@@ -473,6 +473,10 @@ struct lang_hooks
gimplification. */
bool deep_unsharing;
+ /* Return false if we cannot continue executing the immediately
+ following tree. */
+ bool (*tree_may_fallthru) (const_tree);
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
===================================================================
@@ -657,3 +657,12 @@ lhd_end_section (void)
saved_section = NULL;
}
}
+
+/* Return false if we cannot continue executing the tree immediately
+ following T. */
+
+bool
+lhd_tree_may_fallthru (const_tree t ATTRIBUTE_UNUSED)
+{
+ return true;
+}
===================================================================
@@ -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:
@@ -680,8 +681,11 @@ block_may_fallthru (const_tree block)
case CLEANUP_POINT_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 0));
- default:
+ case ERROR_MARK:
return true;
+
+ default:
+ return lang_hooks.tree_may_fallthru (stmt);
}
}
===================================================================
@@ -305,4 +305,21 @@ cp_common_init_ts (void)
MARK_TS_TYPED (CTOR_INITIALIZER);
}
+/* Return false if we cannot continue executing the tree immediately
+ following T. */
+
+bool
+cp_tree_may_fallthru (const_tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case DO_STMT:
+ /* If DO_BODY doesn't fall thru, then DO_STMT doesn't either. */
+ return block_may_fallthru (DO_BODY (t));
+ default:
+ break;
+ }
+ return true;
+}
+
#include "gt-cp-cp-objcp-common.h"
===================================================================
@@ -29,6 +29,7 @@ extern tree objcp_tsubst_copy_and_build
extern bool cp_function_decl_explicit_p (tree decl);
extern void cp_common_init_ts (void);
+extern bool cp_tree_may_fallthru (const_tree);
/* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks
specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
@@ -154,4 +155,7 @@ extern void cp_common_init_ts (void);
#undef LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS
#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS cp_protect_cleanup_actions
+#undef LANG_HOOKS_TREE_MAY_FALLTHRU
+#define LANG_HOOKS_TREE_MAY_FALLTHRU cp_tree_may_fallthru
+
#endif /* GCC_CP_OBJCP_COMMON */
===================================================================
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -Werror -Wreturn-type" } */
+
+/* Test-case from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25973#c4. */
+
+struct Block
+{
+ public:
+ Block();
+ ~Block();
+};
+
+bool func( bool bar )
+{
+ Block block;
+ bool foo = false;
+
+ if( !foo || bar )
+ do { return true; } while( 0 );
+ else
+ do { return false; } while( 0 );
+}
Jakub, This patch fixes the problem reported in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25973#c4 . The test-case listed there is: ... struct Block { public: Block(); ~Block(); }; bool func( bool bar ) { Block block; bool foo = false; if( !foo || bar ) do { return true; } while( 0 ); else do { return false; } while( 0 ); } ... For O0, a spurious warning is generated: ... $ gcc -O0 -Wreturn-type block.C -S: block.C: In function ‘bool func(bool)’: block.C:17:1: warning: control reaches end of non-void function [-Wreturn-type] ... Basically the patch tries to handle DO_STMT in block_may_fallthru, but since it's a cp-tree.def tree, it's done via a language hook. Improving block_may_fallthru helps code in gimplify.c:shortcut_cond_expr() to prevent the superfluous warning: ... /* We only emit the jump over the else clause if we have to--if the then clause may fall through. Otherwise we can wind up with a useless jump and a useless label at the end of gimplified code, which will cause us to think that this conditional as a whole falls through even if it doesn't. If we then inline a function which ends with such a condition, that can cause us to issue an inappropriate warning about control reaching the end of a non-void function. */ jump_over_else = block_may_fallthru (then_); ... Bootstrapped and reg-tested on x86_64. OK for next stage1? Thanks, - Tom