diff options
author | Marek Polacek <mpolacek@gcc.gnu.org> | 2013-12-04 22:47:11 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2013-12-04 22:47:11 +0000 |
commit | 31e071aeb827f49ce2e891620852198e99d44a0c (patch) | |
tree | 20fca81276f1e6d6224300c11a4e10fa89519d41 /gcc/gimple-fold.c | |
parent | 59b6687cceaf95d8c49afee88248cf4fb0a33105 (diff) | |
download | gcc-31e071aeb827f49ce2e891620852198e99d44a0c.zip gcc-31e071aeb827f49ce2e891620852198e99d44a0c.tar.gz gcc-31e071aeb827f49ce2e891620852198e99d44a0c.tar.bz2 |
Implement -fsanitize=signed-integer-overflow.
From-SVN: r205684
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r-- | gcc/gimple-fold.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 7e9ba65..72893cd 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2660,8 +2660,37 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) tree fn; if (gimple_call_internal_p (stmt)) - /* No folding yet for these functions. */ - return NULL_TREE; + { + 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: + return NULL_TREE; + } + tree op0 = (*valueize) (gimple_call_arg (stmt, 0)); + tree op1 = (*valueize) (gimple_call_arg (stmt, 1)); + + if (TREE_CODE (op0) != INTEGER_CST + || TREE_CODE (op1) != INTEGER_CST) + return NULL_TREE; + tree res = fold_binary_loc (loc, subcode, + TREE_TYPE (gimple_call_arg (stmt, 0)), + op0, op1); + if (res + && TREE_CODE (res) == INTEGER_CST + && !TREE_OVERFLOW (res)) + return res; + return NULL_TREE; + } fn = (*valueize) (gimple_call_fn (stmt)); if (TREE_CODE (fn) == ADDR_EXPR |