diff options
author | mpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-04 22:47:11 +0000 |
---|---|---|
committer | mpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-04 22:47:11 +0000 |
commit | 137559b2325c900743803d115c4d8495f9da5d67 (patch) | |
tree | 20fca81276f1e6d6224300c11a4e10fa89519d41 /gcc/tree-vrp.c | |
parent | 85f5275438752595289934e2bbf725d1481f77cc (diff) | |
download | gcc-137559b2325c900743803d115c4d8495f9da5d67.tar.gz |
Implement -fsanitize=signed-integer-overflow.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205684 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 89f2ffd111c..d98b7764b40 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3757,6 +3757,47 @@ extract_range_basic (value_range_t *vr, gimple stmt) break; } } + else if (is_gimple_call (stmt) + && gimple_call_internal_p (stmt)) + { + enum tree_code subcode = ERROR_MARK; + switch (gimple_call_internal_fn (stmt)) + { + case IFN_UBSAN_CHECK_ADD: + subcode = PLUS_EXPR; + break; + case IFN_UBSAN_CHECK_SUB: + subcode = MINUS_EXPR; + break; + case IFN_UBSAN_CHECK_MUL: + subcode = MULT_EXPR; + break; + default: + break; + } + if (subcode != ERROR_MARK) + { + bool saved_flag_wrapv = flag_wrapv; + /* Pretend the arithmetics is wrapping. If there is + any overflow, we'll complain, but will actually do + wrapping operation. */ + flag_wrapv = 1; + extract_range_from_binary_expr (vr, subcode, type, + gimple_call_arg (stmt, 0), + gimple_call_arg (stmt, 1)); + flag_wrapv = saved_flag_wrapv; + + /* If for both arguments vrp_valueize returned non-NULL, + this should have been already folded and if not, it + wasn't folded because of overflow. Avoid removing the + UBSAN_CHECK_* calls in that case. */ + if (vr->type == VR_RANGE + && (vr->min == vr->max + || operand_equal_p (vr->min, vr->max, 0))) + set_value_range_to_varying (vr); + return; + } + } if (INTEGRAL_TYPE_P (type) && gimple_stmt_nonnegative_warnv_p (stmt, &sop)) set_value_range_to_nonnegative (vr, type, |