backport: re PR c++/54046 (wrong control reaches end of non-void function for switch case with throw and default)

Backported from mainline
	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.

	* 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: r195651
This commit is contained in:
Jakub Jelinek 2013-02-01 15:02:33 +01:00 committed by Jakub Jelinek
parent 76013d35b8
commit 5712a08697
11 changed files with 154 additions and 2 deletions

View File

@ -1,6 +1,18 @@
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
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-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/55094

View File

@ -2596,7 +2596,7 @@ gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
$(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_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) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \

View File

@ -1,3 +1,13 @@
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
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.
2013-01-25 Jason Merrill <jason@redhat.com>
PR c++/56104

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

View 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

View File

@ -5918,6 +5918,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 *,

View 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:
@ -680,8 +681,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);
}
}

View File

@ -116,6 +116,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
@ -308,6 +309,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 \
}

View File

@ -465,6 +465,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;

View File

@ -1,6 +1,11 @@
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2012-11-23 Jakub Jelinek <jakub@redhat.com>
PR c++/54046
* g++.dg/warn/Wreturn-type-8.C: New test.
2012-11-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/55094

View File

@ -0,0 +1,90 @@
// PR c++/54046
// { dg-do compile }
// { dg-options "-O0 -Wall -Wno-unused" }
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 ();
}
}