backport: re PR sanitizer/81212 (-Wreturn-type is disabled when used together with -fsanitize=return)

Backported from mainline
	2017-12-02  Jakub Jelinek  <jakub@redhat.com>

	PR c++/81212
	* tree-cfg.c (pass_warn_function_return::execute): Handle
	__builtin_ubsan_handle_missing_return like __builtin_unreachable
	with BUILTINS_LOCATION.

	* g++.dg/ubsan/pr81212.C: New test.

From-SVN: r255722
This commit is contained in:
Jakub Jelinek 2017-12-15 23:09:50 +01:00 committed by Jakub Jelinek
parent e2e1e8d9f8
commit 25d8a020e0
4 changed files with 56 additions and 2 deletions

View File

@ -3,6 +3,11 @@
Backported from mainline
2017-12-02 Jakub Jelinek <jakub@redhat.com>
PR c++/81212
* tree-cfg.c (pass_warn_function_return::execute): Handle
__builtin_ubsan_handle_missing_return like __builtin_unreachable
with BUILTINS_LOCATION.
PR target/78643
PR target/80583
* expr.c (get_inner_reference): If DECL_MODE of a non-bitfield

View File

@ -3,6 +3,11 @@
Backported from mainline
2017-12-02 Jakub Jelinek <jakub@redhat.com>
PR c++/81212
* g++.dg/ubsan/pr81212.C: New test.
2017-12-02 Jakub Jelinek <jakub@redhat.com>
PR target/78643
PR target/80583
* gcc.target/i386/pr80583.c: New test.

View File

@ -0,0 +1,16 @@
// PR c++/81212
// { dg-do compile }
// { dg-options "-Wreturn-type -fsanitize=return" }
struct S
{
S (void *);
void *s;
};
S
foo (bool x, void *y)
{
if (x)
return S (y);
} // { dg-warning "control reaches end of non-void function" }

View File

@ -8917,7 +8917,6 @@ pass_warn_function_return::execute (function *fun)
without returning a value. */
else if (warn_return_type
&& !TREE_NO_WARNING (fun->decl)
&& EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl))))
{
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds)
@ -8931,11 +8930,40 @@ pass_warn_function_return::execute (function *fun)
location = gimple_location (last);
if (location == UNKNOWN_LOCATION)
location = fun->function_end_locus;
warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function");
warning_at (location, OPT_Wreturn_type,
"control reaches end of non-void function");
TREE_NO_WARNING (fun->decl) = 1;
break;
}
}
/* -fsanitize=return turns fallthrough from the end of non-void function
into __builtin___ubsan_handle_missing_return () call.
Recognize those too. */
basic_block bb;
if (!TREE_NO_WARNING (fun->decl) && (flag_sanitize & SANITIZE_RETURN))
FOR_EACH_BB_FN (bb, fun)
if (EDGE_COUNT (bb->succs) == 0)
{
gimple *last = last_stmt (bb);
const enum built_in_function ubsan_missing_ret
= BUILT_IN_UBSAN_HANDLE_MISSING_RETURN;
if (last && gimple_call_builtin_p (last, ubsan_missing_ret))
{
gimple_stmt_iterator gsi = gsi_for_stmt (last);
gsi_prev_nondebug (&gsi);
gimple *prev = gsi_stmt (gsi);
if (prev == NULL)
location = UNKNOWN_LOCATION;
else
location = gimple_location (prev);
if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
location = fun->function_end_locus;
warning_at (location, OPT_Wreturn_type,
"control reaches end of non-void function");
TREE_NO_WARNING (fun->decl) = 1;
break;
}
}
}
return 0;
}