From 1c33c9b70c60fc4c520cb55aa239ffb48ab88f9a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 23 Apr 2014 10:20:12 +0200 Subject: re PR sanitizer/60275 ([UBSAN] Add -f[no-]sanitize-recover/-fsanitize-undefined-trap-on-error to make UBSAN's runtime errors fatal) 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. From-SVN: r209672 --- gcc/c-family/c-ubsan.c | 79 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 26 deletions(-) (limited to 'gcc/c-family/c-ubsan.c') diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index e89ebc1..e4f6f32 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -73,14 +73,22 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) /* 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, enum tree_code code, /* 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, tree size) 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, tree size) 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 (); -- cgit v1.1