public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Yury Gribov <y.gribov@samsung.com>
To: Jakub Jelinek <jakub@redhat.com>, Marek Polacek <polacek@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Alexey Samsonov <samsonov@google.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	Konstantin Serebryany <konstantin.s.serebryany@gmail.com>
Subject: Re: [PATCH] -fsanitize-recover=list
Date: Wed, 22 Oct 2014 08:05:00 -0000	[thread overview]
Message-ID: <544763CA.7090908@samsung.com> (raw)
In-Reply-To: <20141017161334.GF10376@tucnak.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1792 bytes --]

On 10/17/2014 08:13 PM, Jakub Jelinek wrote:
> On Mon, Oct 13, 2014 at 02:47:07PM +0400, Yury Gribov wrote:
>> On 09/30/2014 09:39 PM, Jakub Jelinek wrote:
>>> LGTM, will hack it up soon in GCC then.
>>
>> Do you plan to work on this in near future?
>
> Here is only very lightly tested patch, didn't get to updating
> documentation though, plus there is no testsuite coverage for it.
> Supposedly, most of the tests that use -fno-sanitize-recover
> or -fsanitize-recover in dg-options should be changed to use
> -fno-sanitize-recover= or -fsanitize-recover

Here is an updated patch. I've slightly changed opts.c chunk, added docs 
and updated tests.

> (in some cases for
> the kind that is enabled with -fsanitize= only, in other cases
> perhaps for something covering that and some other options),

Depending on what? I've just passed contents of -fsanitize= to 
-fsanitize-recover=, seems to work fine.

> plus perhaps some new smallish tests that test that if you e.g.
> do -fsanitize=undefined -fno-sanitize-recover=divide , that
> you can recover from several say out of bound shifts, but that
> the first divide will terminate, etc.

Did couple of those.

> There is one not so nice thing, if one requests e.g.
> -fsanitize=null,alignment -fno-sanitize-recover=null -fsanitize-recover=alignment
> (or vice versa), as a single call is used for both alignment and null
> checks, if both are tested, it needs to pick something, the patch
> right now picks recovery rather than abort if the two bits
> in flag_sanitize_recover disagree.  In theory, we could in that case
> just use two separate calls rather than sharing one call, doing the
> check and conditional branch to *_abort () first and if that wasn't true,
> do the other check.

Either that or just issue warning for now.

-Y

[-- Attachment #2: 0001-New-syntax-for-fsanitize-recover.patch --]
[-- Type: text/x-patch, Size: 37891 bytes --]

From 956b59533590fdda49af3afb33063047b0415567 Mon Sep 17 00:00:00 2001
From: Yury Gribov <y.gribov@samsung.com>
Date: Tue, 21 Oct 2014 17:09:37 +0400
Subject: [PATCH] New syntax for -fsanitize-recover.

2014-10-22  Jakub Jelinek  <jakub@redhat.com>
	    Yury Gribov  <y.gribov@samsung.com>

gcc/
	* common.opt (flag_sanitize_recover): New variable.
	(fsanitize-recover): Remove Var/Init, deprecate.
	(fsanitize-recover=): New option.
	* doc/invoke.texi (fsanitize-recover): Update docs.
	* opts.c (finish_options): Use opts->x_flag_sanitize
	instead of flag_sanitize.  Prohibit -fsanitize-recover
	for anything besides UBSan.  Formatting.
	(common_handle_option): Handle OPT_fsanitize_recover_
	and OPT_fsanitize_recover.  Use opts->x_flag_sanitize
	instead of flag_sanitize.
	* asan.c (pass_sanopt::execute): Fix up formatting.
	* ubsan.c (ubsan_expand_bounds_ifn, ubsan_expand_null_ifn,
	ubsan_expand_objsize_ifn, ubsan_build_overflow_builtin,
	instrument_bool_enum_load, ubsan_instrument_float_cast,
	instrument_nonnull_arg, instrument_nonnull_return): Check
	bits in flag_sanitize_recover bitmask instead of
	flag_sanitize_recover as bool flag.

gcc/c-family/
	* c-ubsan.c (ubsan_instrument_division, ubsan_instrument_shift,
	ubsan_instrument_vla): Check bits in flag_sanitize_recover bitmask
	instead of flag_sanitize_recover as bool flag.

gcc/testsuite/
	* c-c++-common/ubsan/align-1.c: Updated cmdline options.
	* c-c++-common/ubsan/align-3.c: Likewise.
	* c-c++-common/ubsan/bounds-1.c: Likewise.
	* c-c++-common/ubsan/div-by-zero-7.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-10.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-7.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-8.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-9.c: Likewise.
	* c-c++-common/ubsan/nonnull-2.c: Likewise.
	* c-c++-common/ubsan/nonnull-3.c: Likewise.
	* c-c++-common/ubsan/object-size-3.c: Likewise.
	* c-c++-common/ubsan/overflow-1.c: Likewise.
	* c-c++-common/ubsan/overflow-add-1.c: Likewise.
	* c-c++-common/ubsan/overflow-add-3.c: Likewise.
	* c-c++-common/ubsan/overflow-mul-1.c: Likewise.
	* c-c++-common/ubsan/overflow-mul-3.c: Likewise.
	* c-c++-common/ubsan/overflow-negate-2.c: Likewise.
	* c-c++-common/ubsan/overflow-sub-1.c: Likewise.
	* c-c++-common/ubsan/pr59503.c: Likewise.
	* c-c++-common/ubsan/pr60613-1.c: Likewise.
	* c-c++-common/ubsan/save-expr-1.c: Likewise.
	* c-c++-common/ubsan/shift-3.c: Likewise.
	* c-c++-common/ubsan/shift-6.c: Likewise.
	* c-c++-common/ubsan/undefined-1.c: Likewise.
	* c-c++-common/ubsan/vla-2.c: Likewise.
	* c-c++-common/ubsan/vla-3.c: Likewise.
	* c-c++-common/ubsan/vla-4.c: Likewise.
	* g++.dg/ubsan/cxx11-shift-1.C: Likewise.
	* g++.dg/ubsan/return-2.C: Likewise.
	* c-c++-common/ubsan/recovery-1.c: New test.
	* c-c++-common/ubsan/recovery-2.c: New test.
	* c-c++-common/ubsan/recovery-3.c: New test.
	* c-c++-common/ubsan/recovery-common.inc: New file.
---
 gcc/asan.c                                         |    6 +--
 gcc/c-family/c-ubsan.c                             |    6 +--
 gcc/common.opt                                     |   12 ++++-
 gcc/doc/invoke.texi                                |   31 +++++++----
 gcc/opts.c                                         |   57 ++++++++++++++------
 gcc/testsuite/c-c++-common/ubsan/align-1.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/align-3.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/bounds-1.c        |    2 +-
 gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c   |    2 +-
 .../c-c++-common/ubsan/float-cast-overflow-10.c    |    2 +-
 .../c-c++-common/ubsan/float-cast-overflow-7.c     |    2 +-
 .../c-c++-common/ubsan/float-cast-overflow-8.c     |    2 +-
 .../c-c++-common/ubsan/float-cast-overflow-9.c     |    2 +-
 gcc/testsuite/c-c++-common/ubsan/nonnull-2.c       |    2 +-
 gcc/testsuite/c-c++-common/ubsan/nonnull-3.c       |    2 +-
 gcc/testsuite/c-c++-common/ubsan/object-size-3.c   |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-1.c      |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c  |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c  |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c  |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c  |    2 +-
 .../c-c++-common/ubsan/overflow-negate-2.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c  |    2 +-
 gcc/testsuite/c-c++-common/ubsan/pr59503.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/pr60613-1.c       |    2 +-
 gcc/testsuite/c-c++-common/ubsan/recovery-1.c      |    9 ++++
 gcc/testsuite/c-c++-common/ubsan/recovery-2.c      |   10 ++++
 gcc/testsuite/c-c++-common/ubsan/recovery-3.c      |    9 ++++
 .../c-c++-common/ubsan/recovery-common.inc         |   19 +++++++
 gcc/testsuite/c-c++-common/ubsan/save-expr-1.c     |    2 +-
 gcc/testsuite/c-c++-common/ubsan/shift-3.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/shift-6.c         |    2 +-
 gcc/testsuite/c-c++-common/ubsan/undefined-1.c     |    2 +-
 gcc/testsuite/c-c++-common/ubsan/vla-2.c           |    2 +-
 gcc/testsuite/c-c++-common/ubsan/vla-3.c           |    2 +-
 gcc/testsuite/c-c++-common/ubsan/vla-4.c           |    2 +-
 gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C         |    2 +-
 gcc/testsuite/g++.dg/ubsan/return-2.C              |    2 +-
 gcc/ubsan.c                                        |   24 +++++----
 39 files changed, 167 insertions(+), 74 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/ubsan/recovery-1.c
 create mode 100644 gcc/testsuite/c-c++-common/ubsan/recovery-2.c
 create mode 100644 gcc/testsuite/c-c++-common/ubsan/recovery-3.c
 create mode 100644 gcc/testsuite/c-c++-common/ubsan/recovery-common.inc

diff --git a/gcc/asan.c b/gcc/asan.c
index 2a61a82..97f0b4c 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2884,10 +2884,8 @@ pass_sanopt::execute (function *fun)
 		  no_next = ubsan_expand_objsize_ifn (&gsi);
 		  break;
 		case IFN_ASAN_CHECK:
-		  {
-		    no_next = asan_expand_check_ifn (&gsi, use_calls);
-		    break;
-		  }
+		  no_next = asan_expand_check_ifn (&gsi, use_calls);
+		  break;
 		default:
 		  break;
 		}
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index 3539c68..5a42303 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -104,7 +104,7 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
 				     NULL_TREE);
       data = build_fold_addr_expr_loc (loc, data);
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & SANITIZE_DIVIDE)
 	  ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
 	  : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
       tt = builtin_decl_explicit (bcode);
@@ -199,7 +199,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
       data = build_fold_addr_expr_loc (loc, data);
 
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & SANITIZE_SHIFT)
 	  ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
 	  : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
       tt = builtin_decl_explicit (bcode);
@@ -229,7 +229,7 @@ ubsan_instrument_vla (location_t loc, tree size)
 				     NULL_TREE);
       data = build_fold_addr_expr_loc (loc, data);
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & SANITIZE_VLA)
 	  ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
 	  : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
       tt = builtin_decl_explicit (bcode);
diff --git a/gcc/common.opt b/gcc/common.opt
index 5db5e1e..3ea5958 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -211,6 +211,10 @@ bool flag_opts_finished
 Variable
 unsigned int flag_sanitize
 
+; What sanitizers should recover from errors
+Variable
+unsigned int flag_sanitize_recover = SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT
+
 ; Flag whether a prefix has been added to dump_base_name
 Variable
 bool dump_base_name_prefixed = false
@@ -879,10 +883,14 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
-fsanitize-recover
-Common Report Var(flag_sanitize_recover) Init(1)
+fsanitize-recover=
+Common Report Joined
 After diagnosing undefined behavior attempt to continue execution
 
+fsanitize-recover
+Common Report
+This switch is deprecated; use -fsanitize-recover= instead
+
 fsanitize-undefined-trap-on-error
 Common Report Var(flag_sanitize_undefined_trap_on_error) Init(0)
 Use trap instead of a library function for undefined behavior sanitization
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 23f272f..349957d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -296,7 +296,7 @@ Objective-C and Objective-C++ Dialects}.
 @item Debugging Options
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
--fsanitize=@var{style} -fsanitize-recover @gol
+-fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol
 -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
@@ -5637,18 +5637,29 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
-@item -fsanitize-recover
+@item -fsanitize-recover@r{[}=@var{opts}@r{]}
 @opindex fsanitize-recover
-By default @option{-fsanitize=undefined} sanitization (and its suboptions
-except for @option{-fsanitize=unreachable} and @option{-fsanitize=return})
-after reporting undefined behavior attempts to continue running the
-program as if no undefined behavior happened.  This means multiple undefined
-behavior runtime errors can be reported in a single program run, and the exit
-code of the program may indicate success even when undefined behavior
-has been reported.  The @option{-fno-sanitize-recover} can be used to alter
-this behavior, only the first detected undefined behavior will be reported
+@opindex fno-sanitize-recover
+@option{-fsanitize-recover=} controls error recovery mode for sanitizers
+mentioned in comma-separated list of @var{opts}.  Enabling this option
+for a sanitizer component would cause it to attempt to continue
+running the program as if no error happened.  This means multiple
+runtime errors can be reported in a single program run, and the exit
+code of the program may indicate success even when errors
+have been reported.  The @option{-fno-sanitize-recover=} can be used to alter
+this behavior, only the first detected error will be reported
 and program will exit after that with non-zero exit code.
 
+Currently this feature only works for @option{-fsanitize=undefined} (and its suboptions
+except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}),
+@option{-fsanitize=float-cast-overflow} and @option{-fsanitize=float-divide-by-zero}.
+For these sanitizers error recovery is turned on by default.
+
+Syntax without explicit @var{opts} parameter is deprecated.  It is equivalent to
+@option{-fsanitize-recover=undefined,float-cast-overflow,float-divide-by-zero}.
+Similarly @option{-fno-sanitize-recover} is equivalent to
+@option{-fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero}.
+
 @item -fsanitize-undefined-trap-on-error
 @opindex fsanitize-undefined-trap-on-error
 The @option{-fsanitize-undefined-trap-on-error} instructs the compiler to
diff --git a/gcc/opts.c b/gcc/opts.c
index 3054196..48ada43 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -879,17 +879,28 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
 
   /* Userspace and kernel ASan conflict with each other and with TSan.  */
 
-  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
-      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+  if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
+      && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
     error_at (loc,
-              "-fsanitize=address is incompatible with "
-              "-fsanitize=kernel-address");
+	      "-fsanitize=address is incompatible with "
+	      "-fsanitize=kernel-address");
 
-  if ((flag_sanitize & SANITIZE_ADDRESS)
-      && (flag_sanitize & SANITIZE_THREAD))
+  if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
+      && (opts->x_flag_sanitize & SANITIZE_THREAD))
     error_at (loc,
-              "-fsanitize=address and -fsanitize=kernel-address "
-              "are incompatible with -fsanitize=thread");
+	      "-fsanitize=address and -fsanitize=kernel-address "
+	      "are incompatible with -fsanitize=thread");
+
+  /* Error recovery is not allowed for ASan and TSan.  */
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_USER_ADDRESS)
+    error_at (loc, "-fsanitize-recover=address is not supported");
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
+    error_at (loc, "-fsanitize-recover=thread is not supported");
+
+  if (opts->x_flag_sanitize_recover & SANITIZE_LEAK)
+    error_at (loc, "-fsanitize-recover=leak is not supported");
 }
 
 #define LEFT_COLUMN	27
@@ -1473,8 +1484,12 @@ common_handle_option (struct gcc_options *opts,
       break;
 
     case OPT_fsanitize_:
+    case OPT_fsanitize_recover_:
       {
 	const char *p = arg;
+	unsigned int *flag
+	  = code == OPT_fsanitize_ ? &opts->x_flag_sanitize
+	  : &opts->x_flag_sanitize_recover;
 	while (*p != 0)
 	  {
 	    static const struct
@@ -1540,32 +1555,35 @@ common_handle_option (struct gcc_options *opts,
 		{
 		  /* Handle both -fsanitize and -fno-sanitize cases.  */
 		  if (value)
-		    flag_sanitize |= spec[i].flag;
+		    *flag |= spec[i].flag;
 		  else
-		    flag_sanitize &= ~spec[i].flag;
+		    *flag &= ~spec[i].flag;
 		  found = true;
 		  break;
 		}
 
 	    if (! found)
 	      error_at (loc,
-			"unrecognized argument to -fsanitize= option: %q.*s",
-			(int) len, p);
+			"unrecognized argument to -fsanitize%s= option: %q.*s",
+			code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
 
 	    if (comma == NULL)
 	      break;
 	    p = comma + 1;
 	  }
 
+	if (code != OPT_fsanitize_)
+	  break;
+
 	/* When instrumenting the pointers, we don't want to remove
 	   the null pointer checks.  */
-	if (flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
-			     | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
+	if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
+				     | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
 	  opts->x_flag_delete_null_pointer_checks = 0;
 
 	/* Kernel ASan implies normal ASan but does not yet support
 	   all features.  */
-	if (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+	if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
 	  {
 	    maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0,
 				   opts->x_param_values,
@@ -1584,6 +1602,15 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fsanitize_recover:
+      if (value)
+	opts->x_flag_sanitize_recover
+	  |= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT;
+      else
+	opts->x_flag_sanitize_recover
+	  &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-1.c b/gcc/testsuite/c-c++-common/ubsan/align-1.c
index 2e40e83..b2ccb30 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 struct S { int a; char b; long long c; short d[10]; };
 struct T { char a; long long b; };
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-3.c b/gcc/testsuite/c-c++-common/ubsan/align-3.c
index a509fa9..bbacc42 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-3.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 int c;
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-1.c b/gcc/testsuite/c-c++-common/ubsan/bounds-1.c
index aa192d3..20e390f 100644
--- a/gcc/testsuite/c-c++-common/ubsan/bounds-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/bounds-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=bounds -fno-sanitize-recover -Wall" } */
+/* { dg-options "-fsanitize=bounds -fno-sanitize-recover=bounds -Wall" } */
 
 /* Don't fail on valid uses.  */
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c
index b65a0bc..5f53bef 100644
--- a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero -fno-sanitize-recover=integer-divide-by-zero" } */
 /* { dg-shouldfail "ubsan" } */
 
 #include <stdio.h>
diff --git a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c
index e95f194..269a0ed 100644
--- a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c
+++ b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c
@@ -1,6 +1,6 @@
 /* { dg-do run { target dfp } } */
 /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=float-cast-overflow -fsanitize-recover" } */
+/* { dg-options "-fsanitize=float-cast-overflow -fsanitize-recover=float-cast-overflow" } */
 /* { dg-additional-options "-DUSE_INT128" { target int128 } } */
 /* FIXME: When _DecimalXX <-> {signed, unsigned} __int128 conversions are
    supported, -DBROKEN_DECIMAL_INT128 can be removed.  */
diff --git a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-7.c b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-7.c
index 3223d5e..69d4628 100644
--- a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-7.c
+++ b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-7.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=float-cast-overflow -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=float-cast-overflow -fno-sanitize-recover=float-cast-overflow" } */
 /* FIXME: When _DecimalXX <-> {signed, unsigned} __int128 conversions are
    supported, -DBROKEN_DECIMAL_INT128 can be removed.  */
 /* { dg-additional-options "-DUSE_DFP -DBROKEN_DECIMAL_INT128" { target dfp } } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c
index 5414a0b..5b1837d 100644
--- a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c
+++ b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=float-cast-overflow -fsanitize-recover -DUSE_FLT_DBL_LDBL" } */
+/* { dg-options "-fsanitize=float-cast-overflow -DUSE_FLT_DBL_LDBL" } */
 /* { dg-additional-options "-DUSE_INT128" { target int128 } } */
 
 #include "float-cast-overflow-7.h"
diff --git a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-9.c b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-9.c
index cadef31..05399e7 100644
--- a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-9.c
+++ b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-9.c
@@ -1,6 +1,6 @@
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
 /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=float-cast-overflow -fsanitize-recover -DUSE_FLOAT80 -DUSE_FLOAT128" } */
+/* { dg-options "-fsanitize=float-cast-overflow -fsanitize-recover=float-cast-overflow -DUSE_FLOAT80 -DUSE_FLOAT128" } */
 /* { dg-additional-options "-DUSE_INT128" { target int128 } } */
 
 #include "float-cast-overflow-8.c"
diff --git a/gcc/testsuite/c-c++-common/ubsan/nonnull-2.c b/gcc/testsuite/c-c++-common/ubsan/nonnull-2.c
index 49a5cf2..3eb6ae7 100644
--- a/gcc/testsuite/c-c++-common/ubsan/nonnull-2.c
+++ b/gcc/testsuite/c-c++-common/ubsan/nonnull-2.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-shouldfail "ubsan" } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 int q, r;
 void *a, *b, *c = (void *) &q, *d, *e, *f = (void *) &q, *g, *h;
diff --git a/gcc/testsuite/c-c++-common/ubsan/nonnull-3.c b/gcc/testsuite/c-c++-common/ubsan/nonnull-3.c
index 80018c2..67fd6dd 100644
--- a/gcc/testsuite/c-c++-common/ubsan/nonnull-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/nonnull-3.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-shouldfail "ubsan" } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 int q, r;
 void *a, *b, *c = (void *) &q, *d, *e, *f = (void *) &q, *g, *h;
diff --git a/gcc/testsuite/c-c++-common/ubsan/object-size-3.c b/gcc/testsuite/c-c++-common/ubsan/object-size-3.c
index 62dc76f..a88081c 100644
--- a/gcc/testsuite/c-c++-common/ubsan/object-size-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/object-size-3.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=object-size -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=object-size -fno-sanitize-recover=object-size" } */
 
 /* Test valid uses.  */
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-1.c b/gcc/testsuite/c-c++-common/ubsan/overflow-1.c
index b0ef259..22bacb3 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow" } */
 
 #ifndef ASM1
 # define ASM1(a) /* Nothing */
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c b/gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c
index b009f5b..960f1b0 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover=signed-integer-overflow" } */
 
 #define SCHAR_MAX __SCHAR_MAX__
 #define SHRT_MAX __SHRT_MAX__
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c b/gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c
index 6475d10..f406276 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover=signed-integer-overflow" } */
 /* { dg-shouldfail "ubsan" } */
 
 #define INT_MAX __INT_MAX__
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c
index 22ea639..04a9ec7 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover=signed-integer-overflow" } */
 
 #define SCHAR_MAX __SCHAR_MAX__
 #define SHRT_MAX __SHRT_MAX__
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c
index 896c0bc..9bca1f8 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow" } */
 
 __attribute__((noinline, noclone)) long long
 mul (long long x, long long y)
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c
index 8b5ffa5..db54b27 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover=signed-integer-overflow" } */
 
 #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
 #define SHRT_MIN (-__SHRT_MAX__ - 1)
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c b/gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c
index 2b10f9e..e92aaf4 100644
--- a/gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover=signed-integer-overflow" } */
 
 #define SCHAR_MAX __SCHAR_MAX__
 #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59503.c b/gcc/testsuite/c-c++-common/ubsan/pr59503.c
index 81447d7..36356d5 100644
--- a/gcc/testsuite/c-c++-common/ubsan/pr59503.c
+++ b/gcc/testsuite/c-c++-common/ubsan/pr59503.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow" } */
 
 int
 main (void)
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr60613-1.c b/gcc/testsuite/c-c++-common/ubsan/pr60613-1.c
index 4c0810b..f358e19 100644
--- a/gcc/testsuite/c-c++-common/ubsan/pr60613-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/pr60613-1.c
@@ -1,6 +1,6 @@
 /* PR sanitizer/60613 */
 /* { dg-do run } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 long long y;
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/recovery-1.c b/gcc/testsuite/c-c++-common/ubsan/recovery-1.c
new file mode 100644
index 0000000..8043a5c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/recovery-1.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined -fsanitize-recover=signed-integer-overflow -w" } */
+
+#include "recovery-common.inc"
+
+/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 2 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/recovery-2.c b/gcc/testsuite/c-c++-common/ubsan/recovery-2.c
new file mode 100644
index 0000000..ad5e410
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/recovery-2.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=signed-integer-overflow -w" } */
+/* { dg-shouldfail "ubsan" } */
+
+#include "recovery-common.inc"
+
+/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*(?!.*signed integer overflow)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/recovery-3.c b/gcc/testsuite/c-c++-common/ubsan/recovery-3.c
new file mode 100644
index 0000000..02f2272
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/recovery-3.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined -w" } */
+
+#include "recovery-common.inc"
+
+/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 2 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/recovery-common.inc b/gcc/testsuite/c-c++-common/ubsan/recovery-common.inc
new file mode 100644
index 0000000..1e0667a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/recovery-common.inc
@@ -0,0 +1,19 @@
+typedef const unsigned long long int CULLI;
+typedef volatile int VI;
+struct s { signed long int a; };
+
+int
+main (void)
+{
+  volatile int shiftcount = 153;
+  volatile int a = __INT_MAX__;
+  volatile int b = __INT_MAX__;
+
+  a << 152;
+  b << shiftcount;
+  a += 1;
+  b += 2;
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c b/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c
index 89ac58c..ff6c5cf 100644
--- a/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fsanitize=shift -Wall -Werror -O -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O -fno-sanitize-recover=shift" } */
 
 static int x;
 int
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-3.c b/gcc/testsuite/c-c++-common/ubsan/shift-3.c
index 67f1b69..d57d73e 100644
--- a/gcc/testsuite/c-c++-common/ubsan/shift-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-3.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover=shift" } */
 
 int
 main (void)
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-6.c b/gcc/testsuite/c-c++-common/ubsan/shift-6.c
index e26e684..d596459 100644
--- a/gcc/testsuite/c-c++-common/ubsan/shift-6.c
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-6.c
@@ -1,6 +1,6 @@
 /* PR sanitizer/58413 */
 /* { dg-do run { target int32plus } } */
-/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover=shift" } */
 
 int x = 7;
 int
diff --git a/gcc/testsuite/c-c++-common/ubsan/undefined-1.c b/gcc/testsuite/c-c++-common/ubsan/undefined-1.c
index 201818d..b67b013 100644
--- a/gcc/testsuite/c-c++-common/ubsan/undefined-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/undefined-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */
 
 int
 foo (int x, int y)
diff --git a/gcc/testsuite/c-c++-common/ubsan/vla-2.c b/gcc/testsuite/c-c++-common/ubsan/vla-2.c
index c767042..9cd4ddf 100644
--- a/gcc/testsuite/c-c++-common/ubsan/vla-2.c
+++ b/gcc/testsuite/c-c++-common/ubsan/vla-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable -fno-sanitize-recover=vla-bound" } */
 
 int
 main (void)
diff --git a/gcc/testsuite/c-c++-common/ubsan/vla-3.c b/gcc/testsuite/c-c++-common/ubsan/vla-3.c
index 06c6939..6003fdd 100644
--- a/gcc/testsuite/c-c++-common/ubsan/vla-3.c
+++ b/gcc/testsuite/c-c++-common/ubsan/vla-3.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover=vla-bound" } */
 
 /* Don't instrument the arrays here.  */
 int
diff --git a/gcc/testsuite/c-c++-common/ubsan/vla-4.c b/gcc/testsuite/c-c++-common/ubsan/vla-4.c
index d47f26b..c9060177 100644
--- a/gcc/testsuite/c-c++-common/ubsan/vla-4.c
+++ b/gcc/testsuite/c-c++-common/ubsan/vla-4.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover" } */
+/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover=vla-bound" } */
 
 int
 main (void)
diff --git a/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C
index 23a7b15..431eab1 100644
--- a/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C
+++ b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover -std=c++11" } */
+/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover=shift -std=c++11" } */
 
 int
 main (void)
diff --git a/gcc/testsuite/g++.dg/ubsan/return-2.C b/gcc/testsuite/g++.dg/ubsan/return-2.C
index a182999..90c48b5 100644
--- a/gcc/testsuite/g++.dg/ubsan/return-2.C
+++ b/gcc/testsuite/g++.dg/ubsan/return-2.C
@@ -1,5 +1,5 @@
 // { dg-do run }
-// { dg-options "-fsanitize=return -fno-sanitize-recover" }
+// { dg-options "-fsanitize=return -fno-sanitize-recover=return" }
 
 struct S { S (); ~S (); };
 
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index dde0418..f143fce 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -638,7 +638,7 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
 			     NULL_TREE, NULL_TREE);
       data = build_fold_addr_expr_loc (loc, data);
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & SANITIZE_BOUNDS)
 	  ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
 	  : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
       tree fn = builtin_decl_explicit (bcode);
@@ -741,7 +741,8 @@ ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
   else
     {
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
+				    | (check_null ? SANITIZE_NULL : 0)))
 	  ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
 	  : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
       tree fn = builtin_decl_implicit (bcode);
@@ -879,7 +880,7 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
 				 NULL_TREE);
 	  data = build_fold_addr_expr_loc (loc, data);
 	  enum built_in_function bcode
-	    = flag_sanitize_recover
+	    = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
 	      ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
 	      : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
 	  tree p = make_ssa_name (pointer_sized_int_node, NULL);
@@ -964,22 +965,22 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
   switch (code)
     {
     case PLUS_EXPR:
-      fn_code = flag_sanitize_recover
+      fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
 		? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
 		: BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
       break;
     case MINUS_EXPR:
-      fn_code = flag_sanitize_recover
+      fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
 		? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
 		: BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
       break;
     case MULT_EXPR:
-      fn_code = flag_sanitize_recover
+      fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
 		? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
 		: BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
       break;
     case NEGATE_EXPR:
-      fn_code = flag_sanitize_recover
+      fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
 		? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
 		: BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
       break;
@@ -1156,7 +1157,8 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
 				     NULL_TREE);
       data = build_fold_addr_expr_loc (loc, data);
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
+				    ? SANITIZE_BOOL : SANITIZE_ENUM))
 	  ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
 	  : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
       tree fn = builtin_decl_explicit (bcode);
@@ -1278,7 +1280,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
 				     ubsan_type_descriptor (type), NULL_TREE,
 				     NULL_TREE);
       enum built_in_function bcode
-	= flag_sanitize_recover
+	= (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
 	  ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
 	  : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
       fn = builtin_decl_explicit (bcode);
@@ -1344,7 +1346,7 @@ instrument_nonnull_arg (gimple_stmt_iterator *gsi)
 					     NULL_TREE);
 	      data = build_fold_addr_expr_loc (loc[0], data);
 	      enum built_in_function bcode
-		= flag_sanitize_recover
+		= (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
 		  ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
 		  : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
 	      tree fn = builtin_decl_explicit (bcode);
@@ -1396,7 +1398,7 @@ instrument_nonnull_return (gimple_stmt_iterator *gsi)
 					 2, loc, NULL_TREE, NULL_TREE);
 	  data = build_fold_addr_expr_loc (loc[0], data);
 	  enum built_in_function bcode
-	    = flag_sanitize_recover
+	    = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
 	      ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
 	      : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
 	  tree fn = builtin_decl_explicit (bcode);
-- 
1.7.9.5


  parent reply	other threads:[~2014-10-22  7:59 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-05  6:54 [PATCH] Enable -fsanitize-recover for KASan Yury Gribov
2014-09-05  7:32 ` Dmitry Vyukov
2014-09-05  8:12   ` Yury Gribov
2014-09-05  8:23     ` Dmitry Vyukov
2014-09-05  8:33       ` Yury Gribov
2014-09-05  9:28         ` Jakub Jelinek
2014-09-05  9:32           ` Yury Gribov
2014-09-05  9:05 ` Andrey Ryabinin
2014-09-05  9:12   ` Yury Gribov
2014-09-15  9:38 ` [PATCH][PING] " Yury Gribov
2014-09-18 10:53   ` Jakub Jelinek
2014-09-18 13:14     ` Yury Gribov
2014-09-18 23:47     ` Joseph S. Myers
2014-09-29 17:21   ` [PATCHv3][PING] " Yury Gribov
2014-09-29 17:44     ` Jakub Jelinek
2014-09-29 21:20       ` Konstantin Serebryany
2014-09-29 22:37         ` Alexey Samsonov
     [not found]         ` <CAGSYnCPwbgZ++2Jt2vE6-ytveSJwSQPZT5umLeKPVWsVjWzwPQ@mail.gmail.com>
2014-09-29 23:17           ` Jakub Jelinek
2014-09-29 23:26             ` Alexey Samsonov
2014-09-30  0:24               ` Konstantin Serebryany
2014-09-30  1:05                 ` Alexey Samsonov
2014-09-30  1:49                   ` Konstantin Serebryany
2014-09-30  5:40                 ` Jakub Jelinek
2014-09-30  7:07                   ` Yury Gribov
2014-09-30 17:26                     ` Alexey Samsonov
2014-09-30 17:33                       ` Jakub Jelinek
2014-09-30 17:36                         ` Alexey Samsonov
2014-09-30 17:39                           ` Jakub Jelinek
2014-10-01 23:21                             ` Alexey Samsonov
2014-10-02  5:58                               ` Jakub Jelinek
2014-10-03 18:54                                 ` Alexey Samsonov
     [not found]                             ` <543BADAB.4090000@samsung.com>
2014-10-17 16:16                               ` [PATCH] -fsanitize-recover=list Jakub Jelinek
2014-10-20 10:44                                 ` Yury Gribov
2014-10-22  8:05                                 ` Yury Gribov [this message]
2014-10-22 10:02                                   ` Jakub Jelinek
2014-11-18  2:50                                 ` Alexey Samsonov
2014-11-18  7:27                                   ` Jakub Jelinek
2014-11-18  8:29                                     ` Alexey Samsonov
2014-11-18  8:34                                       ` Jakub Jelinek
2014-11-18 20:25                                         ` Alexey Samsonov
2014-12-19  2:47                                           ` Alexey Samsonov
2014-12-19  8:14                                             ` Jakub Jelinek
     [not found]                                               ` <CAGSYnCNLoU0p3FGDwb6mMAAOWFz2Te1m7wmWD94PhcADsQs9rQ@mail.gmail.com>
2015-01-05 17:40                                                 ` [PATCH] -f{no-sanitize,{,no-}sanitize-recover}=all support Jakub Jelinek
2015-01-05 20:32                                                   ` Jeff Law
2015-01-05 21:40                                                     ` Jakub Jelinek
2015-01-05 22:02                                                       ` Jakub Jelinek
2015-01-06  9:00                                                         ` Dodji Seketeli
2014-11-18  7:39                                   ` [PATCH] -fsanitize-recover=list Yury Gribov
2014-09-30  6:57                 ` [PATCHv3][PING] Enable -fsanitize-recover for KASan Yury Gribov
2014-09-30  7:14                   ` Yury Gribov
2014-10-23  7:15     ` [PATCHv4] " Yury Gribov
2014-10-23  7:20       ` Jakub Jelinek
2014-10-23  7:30         ` Yury Gribov
2014-10-23  9:55           ` Andrey Ryabinin
2014-10-23 10:00             ` Jakub Jelinek
2014-10-23 10:07               ` Jakub Jelinek
2014-10-23 10:24                 ` Andrey Ryabinin
2014-10-23 10:27                   ` Yury Gribov
2014-10-23 10:11               ` Andrey Ryabinin
2014-10-23 10:17                 ` Jakub Jelinek
2014-10-23 10:38                   ` Yury Gribov
2014-10-23 10:39                     ` Jakub Jelinek
2014-10-23 11:12                       ` Andrey Ryabinin
2014-10-24  8:37                         ` Yury Gribov
2014-10-24  9:46                           ` Dmitry Vyukov
2014-10-24  9:52                             ` Jakub Jelinek
2014-10-24  9:56                               ` Dmitry Vyukov
2014-10-24  9:59                               ` Jakub Jelinek
2014-10-24 10:01                             ` Yury Gribov
2014-10-24 10:21                               ` Dmitry Vyukov
2014-10-28  8:46       ` [PATCH v5] " Yury Gribov
2014-10-28  9:31         ` Jakub Jelinek
2014-10-28 10:15           ` Yury Gribov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=544763CA.7090908@samsung.com \
    --to=y.gribov@samsung.com \
    --cc=dvyukov@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=konstantin.s.serebryany@gmail.com \
    --cc=polacek@redhat.com \
    --cc=samsonov@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).