From: Richard Biener <rguenther@suse.de>
To: Jakub Jelinek <jakub@redhat.com>
Cc: Marek Polacek <polacek@redhat.com>,
Dodji Seketeli <dseketel@redhat.com>,
Konstantin Serebryany <konstantin.s.serebryany@gmail.com>,
Tobias Burnus <burnus@net-b.de>,
gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275)
Date: Wed, 23 Apr 2014 08:14:00 -0000 [thread overview]
Message-ID: <alpine.LSU.2.11.1404231011140.18709@zhemvz.fhfr.qr> (raw)
In-Reply-To: <20140415101156.GB1817@tucnak.redhat.com>
On Tue, 15 Apr 2014, Jakub Jelinek wrote:
> Hi!
>
> This patch adds two new options (compatible with clang) which allow
> users to choose the behavior of undefined behavior sanitization.
>
> By default as before, all undefined behaviors (except for
> __builtin_unreachable and missing return in C++) continue after reporting
> which means that you can get lots of runtime errors from a single program
> run and the exit code will not reflect the failure in that case.
>
> With this patch, one can use -fsanitize=undefined -fno-sanitize-recover,
> which will report just the first undefined behavior and then exit with
> non-zero code.
> Or one can use -fsanitize-undefined-trap-on-error, which will just
> __builtin_trap () on undefined behavior, not report anything and not require
> linking of -lubsan (useful e.g. for the kernel or embedded apps).
> If -fsanitize-undefined-trap-on-error, then -f{,no-}sanitize-recover
> is ignored, as ub traps, of course only the first undefined behavior will
> be "reported" (through the SIGILL/abort).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Works for me.
Thanks,
Richard.
> 2014-04-15 Jakub Jelinek <jakub@redhat.com>
>
> PR sanitizer/60275
> * common.opt (fsanitize-recover, fsanitize-undefined-trap-on-error):
> New options.
> * gcc.c (sanitize_spec_function): Don't return "" for "undefined"
> if flag_sanitize_undefined_trap_on_error.
> * sanitizer.def (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT,
> BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT,
> BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT,
> BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT,
> BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT,
> BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT,
> BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT,
> BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT,
> BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT): New builtins.
> * ubsan.c (ubsan_instrument_unreachable): Return
> __builtin_trap () if flag_sanitize_undefined_trap_on_error.
> (ubsan_expand_null_ifn): Emit __builtin_trap ()
> if flag_sanitize_undefined_trap_on_error and
> __ubsan_handle_type_mismatch_abort if !flag_sanitize_recover.
> (ubsan_expand_null_ifn, ubsan_build_overflow_builtin,
> instrument_bool_enum_load): Emit __builtin_trap () if
> flag_sanitize_undefined_trap_on_error and
> __builtin_handle_*_abort () if !flag_sanitize_recover.
> * doc/invoke.texi (-fsanitize-recover,
> -fsanitize-undefined-trap-on-error): Document.
> c-family/
> * c-ubsan.c (ubsan_instrument_return): Return __builtin_trap ()
> if flag_sanitize_undefined_trap_on_error.
> (ubsan_instrument_division, ubsan_instrument_shift,
> ubsan_instrument_vla): Likewise. Use __ubsan_handle_*_abort ()
> if !flag_sanitize_recover.
> testsuite/
> * g++.dg/ubsan/return-2.C: Revert 2014-03-24 changes, add
> -fno-sanitize-recover to dg-options.
> * g++.dg/ubsan/cxx11-shift-1.C: Remove c++11 target restriction,
> add -std=c++11 to dg-options.
> * g++.dg/ubsan/cxx11-shift-2.C: Likewise.
> * g++.dg/ubsan/cxx1y-vla.C: Remove c++1y target restriction,
> add -std=c++1y to dg-options.
> * c-c++-common/ubsan/undefined-1.c: Revert 2014-03-24 changes, add
> -fno-sanitize-recover to dg-options.
> * c-c++-common/ubsan/overflow-sub-1.c: Likewise.
> * c-c++-common/ubsan/vla-4.c: Likewise.
> * c-c++-common/ubsan/pr59503.c: Likewise.
> * c-c++-common/ubsan/vla-3.c: Likewise.
> * c-c++-common/ubsan/save-expr-1.c: Likewise.
> * c-c++-common/ubsan/overflow-add-1.c: Likewise.
> * c-c++-common/ubsan/shift-3.c: Likewise.
> * c-c++-common/ubsan/overflow-1.c: Likewise.
> * c-c++-common/ubsan/overflow-negate-2.c: Likewise.
> * c-c++-common/ubsan/vla-2.c: Likewise.
> * c-c++-common/ubsan/overflow-mul-1.c: Likewise.
> * c-c++-common/ubsan/pr60613-1.c: Likewise.
> * c-c++-common/ubsan/shift-6.c: Likewise.
> * c-c++-common/ubsan/overflow-mul-3.c: Likewise.
> * c-c++-common/ubsan/overflow-add-3.c: New test.
> * c-c++-common/ubsan/overflow-add-4.c: New test.
> * c-c++-common/ubsan/div-by-zero-6.c: New test.
> * c-c++-common/ubsan/div-by-zero-7.c: New test.
>
> --- gcc/common.opt.jj 2014-04-15 09:57:33.400264838 +0200
> +++ gcc/common.opt 2014-04-15 10:28:10.554519376 +0200
> @@ -862,6 +862,14 @@ fsanitize=
> Common Driver Report Joined
> Select what to sanitize
>
> +fsanitize-recover
> +Common Report Var(flag_sanitize_recover) Init(1)
> +After diagnosing undefined behavior attempt to continue execution
> +
> +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
> +
> fasynchronous-unwind-tables
> Common Report Var(flag_asynchronous_unwind_tables) Optimization
> Generate unwind tables that are exact at each instruction boundary
> --- gcc/gcc.c.jj 2014-04-15 09:57:33.456264545 +0200
> +++ gcc/gcc.c 2014-04-15 10:28:10.555519370 +0200
> @@ -8170,7 +8170,8 @@ sanitize_spec_function (int argc, const
> if (strcmp (argv[0], "thread") == 0)
> return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
> if (strcmp (argv[0], "undefined") == 0)
> - return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
> + return ((flag_sanitize & SANITIZE_UNDEFINED)
> + && !flag_sanitize_undefined_trap_on_error) ? "" : NULL;
> if (strcmp (argv[0], "leak") == 0)
> return ((flag_sanitize
> & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
> --- gcc/sanitizer.def.jj 2014-04-15 09:57:32.819267872 +0200
> +++ gcc/sanitizer.def 2014-04-15 10:28:10.556519365 +0200
> @@ -335,3 +335,39 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HAN
> "__ubsan_handle_load_invalid_value",
> BT_FN_VOID_PTR_PTR,
> ATTR_COLD_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT,
> + "__ubsan_handle_divrem_overflow_abort",
> + BT_FN_VOID_PTR_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT,
> + "__ubsan_handle_shift_out_of_bounds_abort",
> + BT_FN_VOID_PTR_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT,
> + "__ubsan_handle_vla_bound_not_positive_abort",
> + BT_FN_VOID_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT,
> + "__ubsan_handle_type_mismatch_abort",
> + BT_FN_VOID_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT,
> + "__ubsan_handle_add_overflow_abort",
> + BT_FN_VOID_PTR_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT,
> + "__ubsan_handle_sub_overflow_abort",
> + BT_FN_VOID_PTR_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT,
> + "__ubsan_handle_mul_overflow_abort",
> + BT_FN_VOID_PTR_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT,
> + "__ubsan_handle_negate_overflow_abort",
> + BT_FN_VOID_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> +DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT,
> + "__ubsan_handle_load_invalid_value_abort",
> + BT_FN_VOID_PTR_PTR,
> + ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
> --- gcc/ubsan.c.jj 2014-04-15 09:57:33.317265271 +0200
> +++ gcc/ubsan.c 2014-04-15 10:28:10.556519365 +0200
> @@ -516,6 +516,9 @@ ubsan_create_data (const char *name, con
> tree
> ubsan_instrument_unreachable (location_t loc)
> {
> + if (flag_sanitize_undefined_trap_on_error)
> + return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> +
> initialize_sanitizer_builtins ();
> tree data = ubsan_create_data ("__ubsan_unreachable_data", &loc, NULL,
> NULL_TREE);
> @@ -583,16 +586,25 @@ ubsan_expand_null_ifn (gimple_stmt_itera
> set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
>
> /* Put the ubsan builtin call into the newly created BB. */
> - tree fn = builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH);
> - const struct ubsan_mismatch_data m
> - = { build_zero_cst (pointer_sized_int_node), ckind };
> - tree data = ubsan_create_data ("__ubsan_null_data",
> - &loc, &m,
> - ubsan_type_descriptor (TREE_TYPE (ptr), true),
> - NULL_TREE);
> - data = build_fold_addr_expr_loc (loc, data);
> - gimple g = gimple_build_call (fn, 2, data,
> - build_zero_cst (pointer_sized_int_node));
> + gimple g;
> + if (flag_sanitize_undefined_trap_on_error)
> + g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
> + else
> + {
> + enum built_in_function bcode
> + = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
> + : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
> + tree fn = builtin_decl_implicit (bcode);
> + const struct ubsan_mismatch_data m
> + = { build_zero_cst (pointer_sized_int_node), ckind };
> + tree data = ubsan_create_data ("__ubsan_null_data", &loc, &m,
> + ubsan_type_descriptor (TREE_TYPE (ptr),
> + true), NULL_TREE);
> + data = build_fold_addr_expr_loc (loc, data);
> + g = gimple_build_call (fn, 2, data,
> + build_zero_cst (pointer_sized_int_node));
> + }
> gimple_set_location (g, loc);
> gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
> gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
> @@ -662,6 +674,9 @@ tree
> ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
> tree op0, tree op1)
> {
> + if (flag_sanitize_undefined_trap_on_error)
> + return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> +
> tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
> ubsan_type_descriptor (lhstype, false),
> NULL_TREE);
> @@ -670,16 +685,24 @@ ubsan_build_overflow_builtin (tree_code
> switch (code)
> {
> case PLUS_EXPR:
> - fn_code = BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW;
> + fn_code = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
> + : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
> break;
> case MINUS_EXPR:
> - fn_code = BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW;
> + fn_code = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
> + : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
> break;
> case MULT_EXPR:
> - fn_code = BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW;
> + fn_code = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
> + : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
> break;
> case NEGATE_EXPR:
> - fn_code = BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW;
> + fn_code = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
> + : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
> break;
> default:
> gcc_unreachable ();
> @@ -844,17 +867,26 @@ instrument_bool_enum_load (gimple_stmt_i
> gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
> update_stmt (stmt);
>
> - tree data = ubsan_create_data ("__ubsan_invalid_value_data",
> - &loc, NULL,
> - ubsan_type_descriptor (type, false),
> - NULL_TREE);
> - data = build_fold_addr_expr_loc (loc, data);
> - tree fn = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE);
> -
> gsi2 = gsi_after_labels (then_bb);
> - tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
> - true, NULL_TREE, true, GSI_SAME_STMT);
> - g = gimple_build_call (fn, 2, data, val);
> + if (flag_sanitize_undefined_trap_on_error)
> + g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
> + else
> + {
> + tree data = ubsan_create_data ("__ubsan_invalid_value_data", &loc, NULL,
> + ubsan_type_descriptor (type, false),
> + NULL_TREE);
> + data = build_fold_addr_expr_loc (loc, data);
> + enum built_in_function bcode
> + = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
> + : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
> + tree fn = builtin_decl_explicit (bcode);
> +
> + tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
> + true, NULL_TREE, true,
> + GSI_SAME_STMT);
> + g = gimple_build_call (fn, 2, data, val);
> + }
> gimple_set_location (g, loc);
> gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
> }
> --- gcc/c-family/c-ubsan.c.jj 2014-04-15 09:57:33.362265036 +0200
> +++ gcc/c-family/c-ubsan.c 2014-04-15 10:28:10.556519365 +0200
> @@ -73,14 +73,22 @@ ubsan_instrument_division (location_t lo
> /* In case we have a SAVE_EXPR in a conditional context, we need to
> make sure it gets evaluated before the condition. */
> t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
> - tree data = ubsan_create_data ("__ubsan_overflow_data",
> - &loc, NULL,
> - ubsan_type_descriptor (type, false),
> - NULL_TREE);
> - data = build_fold_addr_expr_loc (loc, data);
> - tt = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW);
> - tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
> - ubsan_encode_value (op1));
> + if (flag_sanitize_undefined_trap_on_error)
> + tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> + else
> + {
> + tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
> + ubsan_type_descriptor (type, false),
> + NULL_TREE);
> + data = build_fold_addr_expr_loc (loc, data);
> + enum built_in_function bcode
> + = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
> + : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
> + tt = builtin_decl_explicit (bcode);
> + tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
> + ubsan_encode_value (op1));
> + }
> t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
>
> return t;
> @@ -142,19 +150,28 @@ ubsan_instrument_shift (location_t loc,
> /* In case we have a SAVE_EXPR in a conditional context, we need to
> make sure it gets evaluated before the condition. */
> t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
> - tree data = ubsan_create_data ("__ubsan_shift_data",
> - &loc, NULL,
> - ubsan_type_descriptor (type0, false),
> - ubsan_type_descriptor (type1, false),
> - NULL_TREE);
> -
> - data = build_fold_addr_expr_loc (loc, data);
> -
> t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
> tt ? tt : integer_zero_node);
> - tt = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS);
> - tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
> - ubsan_encode_value (op1));
> +
> + if (flag_sanitize_undefined_trap_on_error)
> + tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> + else
> + {
> + tree data = ubsan_create_data ("__ubsan_shift_data", &loc, NULL,
> + ubsan_type_descriptor (type0, false),
> + ubsan_type_descriptor (type1, false),
> + NULL_TREE);
> +
> + data = build_fold_addr_expr_loc (loc, data);
> +
> + enum built_in_function bcode
> + = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
> + : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
> + tt = builtin_decl_explicit (bcode);
> + tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
> + ubsan_encode_value (op1));
> + }
> t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
>
> return t;
> @@ -169,13 +186,21 @@ ubsan_instrument_vla (location_t loc, tr
> tree t, tt;
>
> t = fold_build2 (LE_EXPR, boolean_type_node, size, build_int_cst (type, 0));
> - tree data = ubsan_create_data ("__ubsan_vla_data",
> - &loc, NULL,
> - ubsan_type_descriptor (type, false),
> - NULL_TREE);
> - data = build_fold_addr_expr_loc (loc, data);
> - tt = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE);
> - tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
> + if (flag_sanitize_undefined_trap_on_error)
> + tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> + else
> + {
> + tree data = ubsan_create_data ("__ubsan_vla_data", &loc, NULL,
> + ubsan_type_descriptor (type, false),
> + NULL_TREE);
> + data = build_fold_addr_expr_loc (loc, data);
> + enum built_in_function bcode
> + = flag_sanitize_recover
> + ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
> + : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
> + tt = builtin_decl_explicit (bcode);
> + tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
> + }
> t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
>
> return t;
> @@ -186,6 +211,8 @@ ubsan_instrument_vla (location_t loc, tr
> tree
> ubsan_instrument_return (location_t loc)
> {
> + if (flag_sanitize_undefined_trap_on_error)
> + return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
> /* It is possible that PCH zapped table with definitions of sanitizer
> builtins. Reinitialize them if needed. */
> initialize_sanitizer_builtins ();
> --- gcc/doc/invoke.texi.jj 2014-04-15 09:57:52.000000000 +0200
> +++ gcc/doc/invoke.texi 2014-04-15 12:09:17.983858622 +0200
> @@ -288,7 +288,8 @@ 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} @gol
> +-fsanitize=@var{style} -fsanitize-recover @gol
> +-fsanitize-undefined-trap-on-error @gol
> -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
> -fdisable-ipa-@var{pass_name} @gol
> -fdisable-rtl-@var{pass_name} @gol
> @@ -5380,6 +5381,26 @@ While @option{-ftrapv} causes traps for
> @option{-fsanitize=undefined} gives a diagnostic message.
> This currently works only for the C family of languages.
>
> +@item -fsanitize-recover
> +@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
> +and program will exit after that with non-zero exit code.
> +
> +@item -fsanitize-undefined-trap-on-error
> +@opindex fsanitize-undefined-trap-on-error
> +The @option{-fsanitize-undefined-trap-on-error} instructs the compiler to
> +report undefined behavior using @code{__builtin_trap ()} rather than
> +a @code{libubsan} library routine. The advantage of this is that the
> +@code{libubsan} library is not needed and will not be linked in, so this
> +is usable even for use in freestanding environments.
> +
> @item -fdump-final-insns@r{[}=@var{file}@r{]}
> @opindex fdump-final-insns
> Dump the final internal representation (RTL) to @var{file}. If the
> --- gcc/testsuite/g++.dg/ubsan/return-2.C.jj 2014-03-25 09:22:04.311136241 +0100
> +++ gcc/testsuite/g++.dg/ubsan/return-2.C 2014-04-15 11:42:41.504233228 +0200
> @@ -1,7 +1,5 @@
> // { dg-do run }
> -// { dg-options "-fsanitize=return" }
> -
> -#include <stdio.h>
> +// { dg-options "-fsanitize=return -fno-sanitize-recover" }
>
> struct S { S (); ~S (); };
>
> @@ -22,12 +20,6 @@ foo (int x)
> int
> main ()
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> foo (1);
> foo (14);
> -
> - fputs ("UBSAN TEST END\n", stderr);
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C.jj 2014-03-25 09:22:04.331136134 +0100
> +++ gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C 2014-04-15 11:42:44.652216672 +0200
> @@ -1,18 +1,10 @@
> -/* { dg-do run { target c++11 } } */
> -/* { dg-options "-fsanitize=shift -w" } */
> -
> -#include <stdio.h>
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover -std=c++11" } */
>
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> int a = 1;
> a <<= 31;
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C.jj 2014-03-10 10:49:56.000000000 +0100
> +++ gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C 2014-04-15 11:28:18.777735556 +0200
> @@ -1,5 +1,5 @@
> -/* { dg-do run { target c++11 } } */
> -/* { dg-options "-fsanitize=shift -w" } */
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=shift -w -std=c++11" } */
>
> int
> main (void)
> --- gcc/testsuite/g++.dg/ubsan/cxx1y-vla.C.jj 2014-03-10 10:49:56.000000000 +0100
> +++ gcc/testsuite/g++.dg/ubsan/cxx1y-vla.C 2014-04-15 11:28:40.570622975 +0200
> @@ -1,5 +1,5 @@
> -/* { dg-do run { target c++1y } } */
> -/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable" } */
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable -std=c++1y" } */
> /* { dg-shouldfail "ubsan" } */
>
> int
> --- gcc/testsuite/c-c++-common/ubsan/undefined-1.c.jj 2014-03-25 09:22:05.226131391 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/undefined-1.c 2014-04-15 11:43:04.064114597 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=undefined" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
>
> int
> foo (int x, int y)
> @@ -21,13 +19,7 @@ bar (int x, int y)
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> foo (3, 2);
> bar (12, 42);
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c.jj 2014-03-25 09:22:05.225131396 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-sub-1.c 2014-04-15 11:43:09.677085087 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
>
> #define SCHAR_MAX __SCHAR_MAX__
> #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
> @@ -20,8 +18,6 @@ check (int i, int j)
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> #if __INT_MAX__ == 2147483647
> /* Here, nothing should fail. */
> volatile int i = -1;
> @@ -61,9 +57,5 @@ main (void)
> d--;
> check (d, 32767);
> #endif
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/vla-4.c.jj 2014-03-25 09:22:05.224131402 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/vla-4.c 2014-04-15 11:43:12.250071561 +0200
> @@ -1,21 +1,13 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=vla-bound" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover" } */
>
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> int x = 1;
> /* Check that the size of an array is evaluated only once. */
> int a[++x];
> if (x != 2)
> __builtin_abort ();
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/pr59503.c.jj 2014-03-25 09:22:05.225131396 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/pr59503.c 2014-04-15 11:43:14.520059628 +0200
> @@ -1,21 +1,13 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
>
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> long long int a = 14;
> long int b = 9;
> asm volatile ("" : "+r" (a), "+r" (b));
> if ((a - b) != 5)
> __builtin_abort ();
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/vla-3.c.jj 2014-03-25 09:22:05.224131402 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/vla-3.c 2014-04-15 11:43:16.707048131 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=vla-bound" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=vla-bound -fno-sanitize-recover" } */
>
> /* Don't instrument the arrays here. */
> int
> @@ -13,13 +11,7 @@ foo (int n, int a[])
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> int a[6] = { };
> int ret = foo (3, a);
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return ret;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/save-expr-1.c.jj 2014-03-25 09:22:05.217131440 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/save-expr-1.c 2014-04-15 11:43:19.240034816 +0200
> @@ -1,19 +1,11 @@
> /* { dg-do compile } */
> -/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=shift -Wall -Werror -O -fno-sanitize-recover" } */
>
> static int x;
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> int o = 1;
> int y = x << o;
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return y;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c.jj 2014-03-25 09:22:05.225131396 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-add-1.c 2014-04-15 11:43:22.331018569 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
>
> #define SCHAR_MAX __SCHAR_MAX__
> #define SHRT_MAX __SHRT_MAX__
> @@ -18,8 +16,6 @@ check (int i, int j)
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> #if __INT_MAX__ == 2147483647
> /* Here, nothing should fail. */
> volatile int j = INT_MAX;
> @@ -59,9 +55,5 @@ main (void)
> d++;
> check (d, -32768);
> #endif
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/shift-3.c.jj 2014-03-25 09:22:05.227131385 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/shift-3.c 2014-04-15 11:43:24.323008099 +0200
> @@ -1,19 +1,11 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=shift -w" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover" } */
>
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> unsigned int a = 1;
> a <<= 31;
> a <<= 1;
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-1.c.jj 2014-03-25 09:22:05.000000000 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-1.c 2014-04-15 11:43:30.257976905 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
>
> #ifndef ASM1
> # define ASM1(a) /* Nothing */
> @@ -53,8 +51,6 @@
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> CHECK (FN1 (char, char, +), 23);
> CHECK (FN1 (char, char, -), 5);
> CHECK (FN1 (char, char, *), 126);
> @@ -261,9 +257,5 @@ main (void)
> CHECK (FN5 (unsigned long int), -77);
> CHECK (FN5 (long long int), -77);
> CHECK (FN5 (unsigned long long int), -77);
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c.jj 2014-03-25 09:22:05.227131385 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-negate-2.c 2014-04-15 11:43:33.411960330 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
>
> #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
> #define SHRT_MIN (-__SHRT_MAX__ - 1)
> @@ -14,8 +12,6 @@
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> volatile signed char c = -SCHAR_MIN;
> CHECK (c, -128);
>
> @@ -37,9 +33,5 @@ main (void)
> volatile long long lli = LLONG_MIN;
> lli = -(unsigned long long) lli;
> CHECK (lli, -0x8000000000000000L);
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/vla-2.c.jj 2014-03-25 09:22:05.218131434 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/vla-2.c 2014-04-15 11:43:35.537949157 +0200
> @@ -1,22 +1,14 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable -fno-sanitize-recover" } */
>
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> const int t = 0;
> struct s {
> int x;
> /* Don't instrument this one. */
> int g[t];
> };
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c.jj 2014-03-25 09:22:05.226131391 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-mul-1.c 2014-04-15 11:43:38.674932672 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
>
> #define SCHAR_MAX __SCHAR_MAX__
> #define SHRT_MAX __SHRT_MAX__
> @@ -18,8 +16,6 @@ check (int i, int j)
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> /* Test integer promotion. */
> #if __SCHAR_MAX__ == 127
> volatile signed char a = -2;
> @@ -45,9 +41,5 @@ main (void)
> o = m * n;
> check (o, INT_MIN);
> #endif
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/pr60613-1.c.jj 2014-03-25 09:22:05.218131434 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/pr60613-1.c 2014-04-15 11:43:41.800916245 +0200
> @@ -1,8 +1,6 @@
> /* PR sanitizer/60613 */
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=undefined" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */
>
> long long y;
>
> @@ -26,16 +24,10 @@ bar (long long x)
> int
> main ()
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> y = 1;
> if (foo (8 - 2040) != 8 - 1)
> __builtin_abort ();
> if (bar (1) != 8 - 1)
> __builtin_abort ();
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/shift-6.c.jj 2014-03-25 09:22:05.228131380 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/shift-6.c 2014-04-15 11:43:44.649901274 +0200
> @@ -1,15 +1,11 @@
> /* PR sanitizer/58413 */
> /* { dg-do run { target int32plus } } */
> -/* { dg-options "-fsanitize=shift -w" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=shift -w -fno-sanitize-recover" } */
>
> int x = 7;
> int
> main (void)
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> /* All of the following should pass. */
> int A[128 >> 5] = {};
> int B[128 << 5] = {};
> @@ -30,9 +26,5 @@ main (void)
> case 128 >> (4 + 1):
> return 1;
> }
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c.jj 2014-03-25 09:22:05.226131391 +0100
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-mul-3.c 2014-04-15 11:43:47.150888133 +0200
> @@ -1,7 +1,5 @@
> /* { dg-do run } */
> -/* { dg-options "-fsanitize=signed-integer-overflow" } */
> -
> -#include <stdio.h>
> +/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover" } */
>
> __attribute__((noinline, noclone)) long long
> mul (long long x, long long y)
> @@ -31,16 +29,10 @@ long long tab[] = {
> int
> main ()
> {
> - fputs ("UBSAN TEST START\n", stderr);
> -
> unsigned int i;
> for (i = 0; i < sizeof (tab) / sizeof (long long); i += 3)
> if (mul (tab[i], tab[i + 1]) != tab[i + 2]
> || mul (tab[i + 1], tab[i]) != tab[i + 2])
> __builtin_abort ();
> -
> - fputs ("UBSAN TEST END\n", stderr);
> return 0;
> }
> -
> -/* { dg-output "UBSAN TEST START(\n|\r\n|\r)UBSAN TEST END" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c.jj 2014-04-15 10:56:15.182674640 +0200
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-add-3.c 2014-04-15 10:57:44.703204633 +0200
> @@ -0,0 +1,17 @@
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fno-sanitize-recover" } */
> +/* { dg-shouldfail "ubsan" } */
> +
> +#define INT_MAX __INT_MAX__
> +#define INT_MIN (-__INT_MAX__ - 1)
> +
> +int
> +main (void)
> +{
> + volatile int j = INT_MAX;
> + volatile int i = 1;
> + volatile int k = j + i;
> + return 0;
> +}
> +
> +/* { dg-output "signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'" } */
> --- gcc/testsuite/c-c++-common/ubsan/overflow-add-4.c.jj 2014-04-15 10:58:10.268070265 +0200
> +++ gcc/testsuite/c-c++-common/ubsan/overflow-add-4.c 2014-04-15 10:58:28.383975015 +0200
> @@ -0,0 +1,15 @@
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable -fsanitize-undefined-trap-on-error" } */
> +/* { dg-shouldfail "ubsan" } */
> +
> +#define INT_MAX __INT_MAX__
> +#define INT_MIN (-__INT_MAX__ - 1)
> +
> +int
> +main (void)
> +{
> + volatile int j = INT_MAX;
> + volatile int i = 1;
> + volatile int k = j + i;
> + return 0;
> +}
> --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-6.c.jj 2014-04-15 10:36:27.241889827 +0200
> +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-6.c 2014-04-15 11:44:36.665628047 +0200
> @@ -0,0 +1,49 @@
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero" } */
> +
> +#include <stdio.h>
> +
> +int x;
> +
> +__attribute__((noinline, noclone))
> +void
> +barrier (void)
> +{
> + asm volatile ("" : : : "memory");
> + if (x)
> + __builtin_exit (1);
> +}
> +
> +int
> +main (void)
> +{
> + volatile int a = 0;
> + volatile long long int b = 0;
> + volatile unsigned int c = 1;
> +
> + barrier (); fputs ("1st\n", stderr); barrier ();
> + a / b;
> + barrier (); fputs ("2nd\n", stderr); barrier ();
> + 0 / 0;
> + barrier (); fputs ("3rd\n", stderr); barrier ();
> + a / 0;
> + barrier (); fputs ("4th\n", stderr); barrier ();
> + 0 / b;
> + barrier (); fputs ("5th\n", stderr); barrier ();
> + 2 / --c;
> + barrier (); fputs ("6th\n", stderr); barrier ();
> +
> + return 0;
> +}
> +
> +/* { dg-output "1st(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "2nd(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "3rd(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "4th(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "5th(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "6th" } */
> --- gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c.jj 2014-04-15 10:49:23.124815653 +0200
> +++ gcc/testsuite/c-c++-common/ubsan/div-by-zero-7.c 2014-04-15 11:44:45.795580108 +0200
> @@ -0,0 +1,41 @@
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero -fno-sanitize-recover" } */
> +/* { dg-shouldfail "ubsan" } */
> +
> +#include <stdio.h>
> +
> +int x;
> +
> +__attribute__((noinline, noclone))
> +void
> +barrier (void)
> +{
> + asm volatile ("" : : : "memory");
> + if (++x == 3)
> + __builtin_exit (0);
> +}
> +
> +int
> +main (void)
> +{
> + volatile int a = 0;
> + volatile long long int b = 0;
> + volatile unsigned int c = 1;
> +
> + barrier (); fputs ("1st\n", stderr); barrier ();
> + a / b;
> + barrier (); fputs ("2nd\n", stderr); barrier ();
> + 0 / 0;
> + barrier (); fputs ("3rd\n", stderr); barrier ();
> + a / 0;
> + barrier (); fputs ("4th\n", stderr); barrier ();
> + 0 / b;
> + barrier (); fputs ("5th\n", stderr); barrier ();
> + 2 / --c;
> + barrier (); fputs ("6th\n", stderr); barrier ();
> +
> + return 0;
> +}
> +
> +/* { dg-output "1st(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*division by zero" } */
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer
next prev parent reply other threads:[~2014-04-23 8:13 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-15 10:12 Jakub Jelinek
2014-04-23 8:14 ` Richard Biener [this message]
2014-05-15 10:30 ` Richard Sandiford
2014-05-15 10:34 ` Jakub Jelinek
2014-05-15 10:38 ` Marek Polacek
2014-05-15 12:42 ` Richard Sandiford
2014-05-15 12:47 ` Marek Polacek
2014-05-15 13:01 ` Richard Biener
2014-05-15 10:39 ` Ramana Radhakrishnan
2014-05-15 15:08 ` Marek Polacek
2014-05-15 15:16 ` Jakub Jelinek
2014-05-15 15:22 ` Marek Polacek
2014-05-15 18:32 ` Toon Moene
2014-05-15 18:37 ` Marek Polacek
2014-05-15 19:11 ` Jakub Jelinek
2014-05-15 19:20 ` Toon Moene
2014-05-15 19:27 ` Marek Polacek
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=alpine.LSU.2.11.1404231011140.18709@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=burnus@net-b.de \
--cc=dseketel@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=konstantin.s.serebryany@gmail.com \
--cc=polacek@redhat.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).