diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29c9af47ab2..f944f765491 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2014-10-22 Jakub Jelinek + Yury Gribov + + * 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. + 2014-10-22 Jiong Wang * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Add missing '\'. diff --git a/gcc/asan.c b/gcc/asan.c index 2a61a8243d3..97f0b4cd61c 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/ChangeLog b/gcc/c-family/ChangeLog index 7d2878db8ee..f95866c729a 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2014-10-22 Jakub Jelinek + Yury Gribov + + * 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. + 2014-10-21 Kirill Yukhin * cilk.c: Revert previous change. diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 3539c68dc8b..5a42303c14a 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 817ac87bf12..da5250b1a27 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 c200399bac5..c9ca404dae1 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 @@ -5642,18 +5642,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 de066bcce07..25f52353218 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 @@ -1517,8 +1528,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 @@ -1584,32 +1599,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, @@ -1628,6 +1646,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/ChangeLog b/gcc/testsuite/ChangeLog index 559f29a4356..49e2537d51d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,40 @@ +2014-10-22 Jakub Jelinek + Yury Gribov + + * c-c++-common/ubsan/align-1.c: Update 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. + 2014-10-22 Jiong Wang * gcc.target/aarch64/pic-constantpool1.c: Add explicit declaration. diff --git a/gcc/testsuite/c-c++-common/ubsan/align-1.c b/gcc/testsuite/c-c++-common/ubsan/align-1.c index 2e40e839261..b2ccb30ec1a 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 a509fa992e5..bbacc4299c6 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 aa192d3787b..20e390f13d5 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 b65a0bc125f..5f53bef74ea 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 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 e95f194cbb3..269a0ed7029 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 3223d5ec575..69d46284b5e 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 5414a0b0e29..5b1837d5a10 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 cadef311121..05399e74022 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 49a5cf208e0..3eb6ae71bec 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 80018c2ef26..67fd6dde2e4 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 62dc76f8b59..a88081c02a9 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 b0ef25924e8..22bacb3cf2f 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 b009f5bb186..960f1b0afaf 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 6475d10469e..f4062768369 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 22ea6398752..04a9ec7c27d 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 896c0bc0279..9bca1f8f5b9 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 8b5ffa5893a..db54b27aa3f 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 2b10f9e5905..e92aaf4ce33 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 81447d7e16b..36356d532c8 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 4c0810b5de2..f358e19da9b 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 00000000000..8043a5cbb6e --- /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 00000000000..ad5e410d9f1 --- /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 00000000000..02f22724999 --- /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 00000000000..1e0667adba4 --- /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 89ac58c281e..ff6c5cff0b1 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 67f1b696177..d57d73e62e8 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 e26e6846ca7..d596459b3ea 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 201818ddd7f..b67b0132822 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 c7670423bab..9cd4ddff219 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 06c69393e7e..6003fdddf3a 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 d47f26bf37f..c9060177606 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 23a7b154d00..431eab12d3e 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 a1829990a81..90c48b5b1d5 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 dde0418dca3..f143fcef6bf 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);