* [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) @ 2014-04-15 10:12 Jakub Jelinek 2014-04-23 8:14 ` Richard Biener 2014-05-15 10:30 ` Richard Sandiford 0 siblings, 2 replies; 17+ messages in thread From: Jakub Jelinek @ 2014-04-15 10:12 UTC (permalink / raw) To: Richard Biener, Marek Polacek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus Cc: gcc-patches 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? 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-04-15 10:12 [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) Jakub Jelinek @ 2014-04-23 8:14 ` Richard Biener 2014-05-15 10:30 ` Richard Sandiford 1 sibling, 0 replies; 17+ messages in thread From: Richard Biener @ 2014-04-23 8:14 UTC (permalink / raw) To: Jakub Jelinek Cc: Marek Polacek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-04-15 10:12 [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) Jakub Jelinek 2014-04-23 8:14 ` Richard Biener @ 2014-05-15 10:30 ` Richard Sandiford 2014-05-15 10:34 ` Jakub Jelinek 1 sibling, 1 reply; 17+ messages in thread From: Richard Sandiford @ 2014-05-15 10:30 UTC (permalink / raw) To: Jakub Jelinek Cc: Richard Biener, Marek Polacek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches Jakub Jelinek <jakub@redhat.com> writes: > 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. Would it make sense for this to be the default for bootstrap-ubsan, so that the bootstrap fails on undefined behaviour? Thanks, Richard ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 10:30 ` Richard Sandiford @ 2014-05-15 10:34 ` Jakub Jelinek 2014-05-15 10:38 ` Marek Polacek 2014-05-15 10:39 ` Ramana Radhakrishnan 0 siblings, 2 replies; 17+ messages in thread From: Jakub Jelinek @ 2014-05-15 10:34 UTC (permalink / raw) To: Richard Biener, Marek Polacek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, rdsandiford On Thu, May 15, 2014 at 11:30:40AM +0100, Richard Sandiford wrote: > Jakub Jelinek <jakub@redhat.com> writes: > > 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. > > Would it make sense for this to be the default for bootstrap-ubsan, > so that the bootstrap fails on undefined behaviour? Perhaps eventually, but is current bootstrap-ubsan really ubsan error free on at least the major targets? I've made some efforts towards that goal on x86_64-linux, but haven't tried bootstrap-ubsan recently. Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 10:34 ` Jakub Jelinek @ 2014-05-15 10:38 ` Marek Polacek 2014-05-15 12:42 ` Richard Sandiford 2014-05-15 10:39 ` Ramana Radhakrishnan 1 sibling, 1 reply; 17+ messages in thread From: Marek Polacek @ 2014-05-15 10:38 UTC (permalink / raw) To: Jakub Jelinek Cc: Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, rdsandiford On Thu, May 15, 2014 at 12:33:57PM +0200, Jakub Jelinek wrote: > On Thu, May 15, 2014 at 11:30:40AM +0100, Richard Sandiford wrote: > > Jakub Jelinek <jakub@redhat.com> writes: > > > 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. > > > > Would it make sense for this to be the default for bootstrap-ubsan, > > so that the bootstrap fails on undefined behaviour? > > Perhaps eventually, but is current bootstrap-ubsan really ubsan error free > on at least the major targets? I've made some efforts towards that goal on > x86_64-linux, but haven't tried bootstrap-ubsan recently. It's not, I'm seeing many /home/marek/src/gcc/gcc/wide-int.h:1734:7: runtime error: shift exponent 64 is too large for 64-bit type 'long unsigned int' plus I think I remember some other fails. Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 10:38 ` Marek Polacek @ 2014-05-15 12:42 ` Richard Sandiford 2014-05-15 12:47 ` Marek Polacek 0 siblings, 1 reply; 17+ messages in thread From: Richard Sandiford @ 2014-05-15 12:42 UTC (permalink / raw) To: Marek Polacek Cc: Jakub Jelinek, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches Marek Polacek <polacek@redhat.com> writes: > On Thu, May 15, 2014 at 12:33:57PM +0200, Jakub Jelinek wrote: >> On Thu, May 15, 2014 at 11:30:40AM +0100, Richard Sandiford wrote: >> > Jakub Jelinek <jakub@redhat.com> writes: >> > > 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. >> > >> > Would it make sense for this to be the default for bootstrap-ubsan, >> > so that the bootstrap fails on undefined behaviour? >> >> Perhaps eventually, but is current bootstrap-ubsan really ubsan error free >> on at least the major targets? I've made some efforts towards that goal on >> x86_64-linux, but haven't tried bootstrap-ubsan recently. > > It's not, I'm seeing many > /home/marek/src/gcc/gcc/wide-int.h:1734:7: runtime error: shift > exponent 64 is too large for 64-bit type 'long unsigned int' > plus I think I remember some other fails. Yeah, like Richard said on IRC a few days ago, this is partly due to the zero-precision stuff. We need to ween ubsan off void_zero_node and then see where things stand. Thanks, Richard ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 12:42 ` Richard Sandiford @ 2014-05-15 12:47 ` Marek Polacek 2014-05-15 13:01 ` Richard Biener 0 siblings, 1 reply; 17+ messages in thread From: Marek Polacek @ 2014-05-15 12:47 UTC (permalink / raw) To: Jakub Jelinek, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, rsandifo On Thu, May 15, 2014 at 01:42:20PM +0100, Richard Sandiford wrote: > > It's not, I'm seeing many > > /home/marek/src/gcc/gcc/wide-int.h:1734:7: runtime error: shift > > exponent 64 is too large for 64-bit type 'long unsigned int' > > plus I think I remember some other fails. > > Yeah, like Richard said on IRC a few days ago, this is partly due to the > zero-precision stuff. We need to ween ubsan off void_zero_node and then > see where things stand. Yeah, I don't like void_zero_node that much; I'll see if I can stamp it out. But note that I see many uses of void_zero_node in the C++ FE. (ubsan uses void_zero_node only in the c-family/ subdirectory.) Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 12:47 ` Marek Polacek @ 2014-05-15 13:01 ` Richard Biener 0 siblings, 0 replies; 17+ messages in thread From: Richard Biener @ 2014-05-15 13:01 UTC (permalink / raw) To: Marek Polacek Cc: Jakub Jelinek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, rsandifo On Thu, 15 May 2014, Marek Polacek wrote: > On Thu, May 15, 2014 at 01:42:20PM +0100, Richard Sandiford wrote: > > > It's not, I'm seeing many > > > /home/marek/src/gcc/gcc/wide-int.h:1734:7: runtime error: shift > > > exponent 64 is too large for 64-bit type 'long unsigned int' > > > plus I think I remember some other fails. > > > > Yeah, like Richard said on IRC a few days ago, this is partly due to the > > zero-precision stuff. We need to ween ubsan off void_zero_node and then > > see where things stand. > > Yeah, I don't like void_zero_node that much; I'll see if I can stamp it > out. But note that I see many uses of void_zero_node in the C++ FE. > (ubsan uses void_zero_node only in the c-family/ subdirectory.) They shouldn't survive gimplification though. I suggest to add a check for verify_expr to catch them and ICE if they appear in the IL. Richard. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 10:34 ` Jakub Jelinek 2014-05-15 10:38 ` Marek Polacek @ 2014-05-15 10:39 ` Ramana Radhakrishnan 2014-05-15 15:08 ` Marek Polacek 1 sibling, 1 reply; 17+ messages in thread From: Ramana Radhakrishnan @ 2014-05-15 10:39 UTC (permalink / raw) To: Jakub Jelinek Cc: Richard Biener, Marek Polacek, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 11:33 AM, Jakub Jelinek <jakub@redhat.com> wrote: > On Thu, May 15, 2014 at 11:30:40AM +0100, Richard Sandiford wrote: >> Jakub Jelinek <jakub@redhat.com> writes: >> > 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. >> >> Would it make sense for this to be the default for bootstrap-ubsan, >> so that the bootstrap fails on undefined behaviour? > > Perhaps eventually, but is current bootstrap-ubsan really ubsan error free > on at least the major targets? I've made some efforts towards that goal on > x86_64-linux, but haven't tried bootstrap-ubsan recently. What's the overhead with bootstrap-ubsan ? Ramana > > Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 10:39 ` Ramana Radhakrishnan @ 2014-05-15 15:08 ` Marek Polacek 2014-05-15 15:16 ` Jakub Jelinek 2014-05-15 18:32 ` Toon Moene 0 siblings, 2 replies; 17+ messages in thread From: Marek Polacek @ 2014-05-15 15:08 UTC (permalink / raw) To: ramrad01 Cc: Jakub Jelinek, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 11:39:26AM +0100, Ramana Radhakrishnan wrote: > What's the overhead with bootstrap-ubsan ? I timed normal bootstrap and bootstrap-ubsan on x86_64, 24 cores, Intel(R) Xeon(R) CPU X5670 @ 2.93GHz (aka cfarm 20) and the results: --enable-languages=all real 35m10.419s user 204m5.613s sys 6m15.615s --enable-languages=all --with-build-config=bootstrap-ubsan real 71m39.338s user 347m53.409s sys 7m44.281s Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 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 1 sibling, 1 reply; 17+ messages in thread From: Jakub Jelinek @ 2014-05-15 15:16 UTC (permalink / raw) To: Marek Polacek Cc: ramrad01, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 05:08:10PM +0200, Marek Polacek wrote: > On Thu, May 15, 2014 at 11:39:26AM +0100, Ramana Radhakrishnan wrote: > > What's the overhead with bootstrap-ubsan ? > > I timed normal bootstrap and bootstrap-ubsan on x86_64, 24 cores, > Intel(R) Xeon(R) CPU X5670 @ 2.93GHz (aka cfarm 20) and the results: > > --enable-languages=all > > real 35m10.419s > user 204m5.613s > sys 6m15.615s > > --enable-languages=all --with-build-config=bootstrap-ubsan > > real 71m39.338s > user 347m53.409s > sys 7m44.281s Note that doesn't mean -fsanitize=undefined generated code is twice as slow as code compiled without it, guess most of the extra overhead is actually compile time (mostly larger cfg due to all the extra checks). Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 15:16 ` Jakub Jelinek @ 2014-05-15 15:22 ` Marek Polacek 0 siblings, 0 replies; 17+ messages in thread From: Marek Polacek @ 2014-05-15 15:22 UTC (permalink / raw) To: Jakub Jelinek Cc: ramrad01, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 05:16:00PM +0200, Jakub Jelinek wrote: > On Thu, May 15, 2014 at 05:08:10PM +0200, Marek Polacek wrote: > > On Thu, May 15, 2014 at 11:39:26AM +0100, Ramana Radhakrishnan wrote: > > > What's the overhead with bootstrap-ubsan ? > > > > I timed normal bootstrap and bootstrap-ubsan on x86_64, 24 cores, > > Intel(R) Xeon(R) CPU X5670 @ 2.93GHz (aka cfarm 20) and the results: > > > > --enable-languages=all > > > > real 35m10.419s > > user 204m5.613s > > sys 6m15.615s > > > > --enable-languages=all --with-build-config=bootstrap-ubsan > > > > real 71m39.338s > > user 347m53.409s > > sys 7m44.281s > > Note that doesn't mean -fsanitize=undefined generated code is twice as slow > as code compiled without it, guess most of the extra overhead is actually > compile time (mostly larger cfg due to all the extra checks). And I think the main offender will be the NULL checking with its extra bbs. So to alleviate the cfg size one can use -fsanitize=undefined -fno-sanitize=null - I'd expect this to make a significant difference. Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 15:08 ` Marek Polacek 2014-05-15 15:16 ` Jakub Jelinek @ 2014-05-15 18:32 ` Toon Moene 2014-05-15 18:37 ` Marek Polacek 1 sibling, 1 reply; 17+ messages in thread From: Toon Moene @ 2014-05-15 18:32 UTC (permalink / raw) To: Marek Polacek, ramrad01 Cc: Jakub Jelinek, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On 05/15/2014 05:08 PM, Marek Polacek wrote: > On Thu, May 15, 2014 at 11:39:26AM +0100, Ramana Radhakrishnan wrote: >> What's the overhead with bootstrap-ubsan ? > > I timed normal bootstrap and bootstrap-ubsan on x86_64, 24 cores, > Intel(R) Xeon(R) CPU X5670 @ 2.93GHz (aka cfarm 20) and the results: > > --enable-languages=all > > real 35m10.419s > user 204m5.613s > sys 6m15.615s > > --enable-languages=all --with-build-config=bootstrap-ubsan > > real 71m39.338s > user 347m53.409s > sys 7m44.281s And don't underestimate the *usefulness* of this - if you don't have the resources to do a ubsan bootstrap, download mine from last night (x86_64-linux-gnu): http://moene.org/~toon/gcc-tests.log.gz [ I hope there is a way to discard color codings when writing error messages to a file, ugh ] Kind regards, -- Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290 Saturnushof 14, 3738 XG Maartensdijk, The Netherlands At home: http://moene.org/~toon/; weather: http://moene.org/~hirlam/ Progress of GNU Fortran: http://gcc.gnu.org/wiki/GFortran#news ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 18:32 ` Toon Moene @ 2014-05-15 18:37 ` Marek Polacek 2014-05-15 19:11 ` Jakub Jelinek 0 siblings, 1 reply; 17+ messages in thread From: Marek Polacek @ 2014-05-15 18:37 UTC (permalink / raw) To: Toon Moene Cc: ramrad01, Jakub Jelinek, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 08:32:36PM +0200, Toon Moene wrote: > On 05/15/2014 05:08 PM, Marek Polacek wrote: > > >On Thu, May 15, 2014 at 11:39:26AM +0100, Ramana Radhakrishnan wrote: > >>What's the overhead with bootstrap-ubsan ? > > > >I timed normal bootstrap and bootstrap-ubsan on x86_64, 24 cores, > >Intel(R) Xeon(R) CPU X5670 @ 2.93GHz (aka cfarm 20) and the results: > > > >--enable-languages=all > > > >real 35m10.419s > >user 204m5.613s > >sys 6m15.615s > > > >--enable-languages=all --with-build-config=bootstrap-ubsan > > > >real 71m39.338s > >user 347m53.409s > >sys 7m44.281s > > And don't underestimate the *usefulness* of this - if you don't have the > resources to do a ubsan bootstrap, download mine from last night > (x86_64-linux-gnu): http://moene.org/~toon/gcc-tests.log.gz > > [ I hope there is a way to discard color codings when writing error messages > to a file, ugh ] Sure, -fdiagnostics-color=auto "means to use color only when the standard error is a terminal", or -fdiagnostics-color=never to turn it off completely (testsuite uses the latter). Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 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 0 siblings, 2 replies; 17+ messages in thread From: Jakub Jelinek @ 2014-05-15 19:11 UTC (permalink / raw) To: Marek Polacek Cc: Toon Moene, ramrad01, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 08:37:07PM +0200, Marek Polacek wrote: > > And don't underestimate the *usefulness* of this - if you don't have the > > resources to do a ubsan bootstrap, download mine from last night > > (x86_64-linux-gnu): http://moene.org/~toon/gcc-tests.log.gz > > > > [ I hope there is a way to discard color codings when writing error messages > > to a file, ugh ] > > Sure, -fdiagnostics-color=auto "means to use color only when the > standard error is a terminal", or -fdiagnostics-color=never to turn it > off completely (testsuite uses the latter). I guess Toon meant that there is no easy way? to get rid of the color stuff in libsanitizer messages. Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 19:11 ` Jakub Jelinek @ 2014-05-15 19:20 ` Toon Moene 2014-05-15 19:27 ` Marek Polacek 1 sibling, 0 replies; 17+ messages in thread From: Toon Moene @ 2014-05-15 19:20 UTC (permalink / raw) To: Jakub Jelinek, Marek Polacek Cc: ramrad01, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On 05/15/2014 09:10 PM, Jakub Jelinek wrote: > On Thu, May 15, 2014 at 08:37:07PM +0200, Marek Polacek wrote: >> Sure, -fdiagnostics-color=auto "means to use color only when the >> standard error is a terminal", or -fdiagnostics-color=never to turn it >> off completely (testsuite uses the latter). > > I guess Toon meant that there is no easy way? to get rid of the color > stuff in libsanitizer messages. Sure. The point is that the testsuite runs only write to a *file*, so why should I get color-coded error messages like this: ESC[1m/home/toon/compilers/trunk/gcc/config/i386/i386.c:6577:60:ESC[1mESC[31m runtime error: ESC[1mESC[0mESC[1mload of value 32763, which is not a valid value for type 'x86_64_reg_class'ESC[1mESC[0m ? It makes precise grepping needlessly hard ... Otherwise, thanks very much for this work - definitely appreciated ! -- Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290 Saturnushof 14, 3738 XG Maartensdijk, The Netherlands At home: http://moene.org/~toon/; weather: http://moene.org/~hirlam/ Progress of GNU Fortran: http://gcc.gnu.org/wiki/GFortran#news ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) 2014-05-15 19:11 ` Jakub Jelinek 2014-05-15 19:20 ` Toon Moene @ 2014-05-15 19:27 ` Marek Polacek 1 sibling, 0 replies; 17+ messages in thread From: Marek Polacek @ 2014-05-15 19:27 UTC (permalink / raw) To: Jakub Jelinek Cc: Toon Moene, ramrad01, Richard Biener, Dodji Seketeli, Konstantin Serebryany, Tobias Burnus, gcc-patches, Richard Sandiford On Thu, May 15, 2014 at 09:10:55PM +0200, Jakub Jelinek wrote: > I guess Toon meant that there is no easy way? to get rid of the color > stuff in libsanitizer messages. Yikes. I think there's no way yet; UBSAN_OPTIONS envvar, similar to e.g. ASAN_OPTIONS, isn't supported yet it seems. Marek ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2014-05-15 19:27 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-04-15 10:12 [PATCH] Add support for -fno-sanitize-recover and -fsanitize-undefined-trap-on-error (PR sanitizer/60275) Jakub Jelinek 2014-04-23 8:14 ` Richard Biener 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
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).