This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix ICEs when -fsanitize={undefined,address,thread} is used during -c -flto but not during the final link (PR sanitizer/78708)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 10 Dec 2016 07:19:22 +0100
- Subject: Re: [PATCH] Fix ICEs when -fsanitize={undefined,address,thread} is used during -c -flto but not during the final link (PR sanitizer/78708)
- Authentication-results: sourceware.org; auth=none
- References: <20161209193026.GH3541@tucnak.redhat.com>
On December 9, 2016 8:30:26 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>If some TUs are compiled with -flto -fsanitize={undefined,address} or
>-fsanitize=thread, there might be some internal calls in them which
>require
>sanopt pass to lower them. If the final link is performed without
>the corresponding -fsanitize=* options (user bug), that pass might not
>be
>run at all and we'd ICE. With this patch we throw away unexpected
>sanitizer
>ifns and so worst case the final link will fail because of missing
>libasan,
>libubsan or libtsan symbols.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
>2016-12-09 Jakub Jelinek <jakub@redhat.com>
>
> PR sanitizer/78708
> * lto-streamer-in.c (input_function): In addition to debug stmts
> without -g, remove IFN_*SAN_* calls if corresponding flag_sanitize
> bit is not enabled.
>
>--- gcc/lto-streamer-in.c.jj 2016-10-31 13:28:11.000000000 +0100
>+++ gcc/lto-streamer-in.c 2016-12-09 14:54:12.050362649 +0100
>@@ -1110,15 +1110,59 @@ input_function (tree fn_decl, struct dat
> while (!gsi_end_p (bsi))
> {
> gimple *stmt = gsi_stmt (bsi);
>+ bool remove = false;
> /* If we're recompiling LTO objects with debug stmts but
> we're not supposed to have debug stmts, remove them now.
> We can't remove them earlier because this would cause uid
> mismatches in fixups, but we can do it at this point, as
>- long as debug stmts don't require fixups. */
>- if (!MAY_HAVE_DEBUG_STMTS && !flag_wpa && is_gimple_debug (stmt))
>+ long as debug stmts don't require fixups.
>+ Similarly remove all IFN_*SAN_* internal calls */
>+ if (!flag_wpa)
>+ {
>+ if (!MAY_HAVE_DEBUG_STMTS && is_gimple_debug (stmt))
>+ remove = true;
>+ if (is_gimple_call (stmt)
>+ && gimple_call_internal_p (stmt))
>+ {
>+ switch (gimple_call_internal_fn (stmt))
>+ {
>+ case IFN_UBSAN_NULL:
>+ if ((flag_sanitize
>+ & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) == 0)
>+ remove = true;
>+ break;
>+ case IFN_UBSAN_BOUNDS:
>+ if ((flag_sanitize & SANITIZE_BOUNDS) == 0)
>+ remove = true;
>+ break;
>+ case IFN_UBSAN_VPTR:
>+ if ((flag_sanitize & SANITIZE_VPTR) == 0)
>+ remove = true;
>+ break;
>+ case IFN_UBSAN_OBJECT_SIZE:
>+ if ((flag_sanitize & SANITIZE_OBJECT_SIZE) == 0)
>+ remove = true;
>+ break;
>+ case IFN_ASAN_MARK:
>+ if ((flag_sanitize & SANITIZE_ADDRESS) == 0)
>+ remove = true;
>+ break;
>+ case IFN_TSAN_FUNC_EXIT:
>+ if ((flag_sanitize & SANITIZE_THREAD) == 0)
>+ remove = true;
>+ break;
>+ default:
>+ break;
>+ }
>+ gcc_assert (!remove || gimple_call_lhs (stmt) == NULL_TREE);
>+ }
>+ }
>+ if (remove)
> {
> gimple_stmt_iterator gsi = bsi;
> gsi_next (&bsi);
>+ unlink_stmt_vdef (stmt);
>+ release_defs (stmt);
> gsi_remove (&gsi, true);
> }
> else
>
> Jakub