From: Jakub Jelinek Date: Mon, 25 Jun 2018 16:57:59 +0000 (+0200) Subject: backport: re PR sanitizer/81212 (-Wreturn-type is disabled when used together with... X-Git-Tag: releases/gcc-6.5.0~241 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6028f46a2fdfe5116aadb5fb8f68e56b9c1b6fbc;p=thirdparty%2Fgcc.git backport: re PR sanitizer/81212 (-Wreturn-type is disabled when used together with -fsanitize=return) Backported from mainline 2017-12-02 Jakub Jelinek 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: r262042 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 310eda8082d8..e961c0e34222 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,11 @@ Backported from mainline 2017-12-02 Jakub Jelinek + 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 204fea0c8f8a..67023267d1b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2017-12-02 Jakub Jelinek + PR c++/81212 + * g++.dg/ubsan/pr81212.C: New test. + PR target/78643 PR target/80583 * gcc.target/i386/pr80583.c: New test. diff --git a/gcc/testsuite/g++.dg/ubsan/pr81212.C b/gcc/testsuite/g++.dg/ubsan/pr81212.C new file mode 100644 index 000000000000..ce92a07dceb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr81212.C @@ -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" } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 380f6898db75..983fd704f6bc 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -8752,7 +8752,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) @@ -8766,11 +8765,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; }