diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-23 08:20:12 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-23 08:20:12 +0000 |
commit | 7311d7c1359e55ae90af4485b0883ea31204637f (patch) | |
tree | 63757a4be556a608b41730e5646da6118aa415c9 /gcc/ubsan.c | |
parent | a3371bc31af89f3899392b5ec270696ff4247cad (diff) | |
download | gcc-7311d7c1359e55ae90af4485b0883ea31204637f.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209672 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ubsan.c')
-rw-r--r-- | gcc/ubsan.c | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/gcc/ubsan.c b/gcc/ubsan.c index cf25aa3edf6..d9d740c7cd3 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -516,6 +516,9 @@ ubsan_create_data (const char *name, const location_t *ploc, 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_iterator gsi) 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 code, location_t loc, tree lhstype, 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_iterator *gsi) 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); } |