Skip to content

Commit 6c152c9

Browse files
committed
internal-fn: Temporarily disable flag_trapv during .{ADD,SUB,MUL}_OVERFLOW etc. expansion [PR114753]
__builtin_{add,sub,mul}_overflow{,_p} builtins are well defined for all inputs even for -ftrapv, and the -fsanitize=signed-integer-overflow ifns shouldn't abort in libgcc but emit the desired ubsan diagnostics or abort depending on -fsanitize* setting regardless of -ftrapv. The expansion of these internal functions uses expand_expr* in various places (e.g. MULT_EXPR at least in 2 spots), so temporarily disabling flag_trapv in all those spots would be hard. The following patch disables it around the bodies of 3 functions which can do the expand_expr calls. If it was in the C++ FE, I'd use some RAII sentinel, but I don't think we have one in the middle-end. 2024-04-18 Jakub Jelinek <[email protected]> PR middle-end/114753 * internal-fn.cc (expand_mul_overflow): Save flag_trapv and temporarily clear it for the duration of the function, then restore previous value. (expand_vector_ubsan_overflow): Likewise. (expand_arith_overflow): Likewise. * gcc.dg/pr114753.c: New test.
1 parent 6e62ede commit 6c152c9

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

gcc/internal-fn.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,7 +1631,11 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
16311631
rtx target = NULL_RTX;
16321632
signop sign;
16331633
enum insn_code icode;
1634+
int save_flag_trapv = flag_trapv;
16341635

1636+
/* We don't want any __mulv?i3 etc. calls from the expansion of
1637+
these internal functions, so disable -ftrapv temporarily. */
1638+
flag_trapv = 0;
16351639
done_label = gen_label_rtx ();
16361640
do_error = gen_label_rtx ();
16371641

@@ -2479,6 +2483,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
24792483
else
24802484
expand_arith_overflow_result_store (lhs, target, mode, res);
24812485
}
2486+
flag_trapv = save_flag_trapv;
24822487
}
24832488

24842489
/* Expand UBSAN_CHECK_* internal function if it has vector operands. */
@@ -2499,7 +2504,11 @@ expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
24992504
rtx resvr = NULL_RTX;
25002505
unsigned HOST_WIDE_INT const_cnt = 0;
25012506
bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2507+
int save_flag_trapv = flag_trapv;
25022508

2509+
/* We don't want any __mulv?i3 etc. calls from the expansion of
2510+
these internal functions, so disable -ftrapv temporarily. */
2511+
flag_trapv = 0;
25032512
if (lhs)
25042513
{
25052514
optab op;
@@ -2629,6 +2638,7 @@ expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
26292638
}
26302639
else if (resvr)
26312640
emit_move_insn (lhsr, resvr);
2641+
flag_trapv = save_flag_trapv;
26322642
}
26332643

26342644
/* Expand UBSAN_CHECK_ADD call STMT. */
@@ -2707,7 +2717,11 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
27072717
prec0 = MIN (prec0, pr);
27082718
pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
27092719
prec1 = MIN (prec1, pr);
2720+
int save_flag_trapv = flag_trapv;
27102721

2722+
/* We don't want any __mulv?i3 etc. calls from the expansion of
2723+
these internal functions, so disable -ftrapv temporarily. */
2724+
flag_trapv = 0;
27112725
/* If uns0_p && uns1_p, precop is minimum needed precision
27122726
of unsigned type to hold the exact result, otherwise
27132727
precop is minimum needed precision of signed type to
@@ -2748,6 +2762,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
27482762
ops.location = loc;
27492763
rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
27502764
expand_arith_overflow_result_store (lhs, target, mode, tem);
2765+
flag_trapv = save_flag_trapv;
27512766
return;
27522767
}
27532768

@@ -2771,6 +2786,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
27712786
if (integer_zerop (arg0) && !unsr_p)
27722787
{
27732788
expand_neg_overflow (loc, lhs, arg1, false, NULL);
2789+
flag_trapv = save_flag_trapv;
27742790
return;
27752791
}
27762792
/* FALLTHRU */
@@ -2781,6 +2797,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
27812797
case MULT_EXPR:
27822798
expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
27832799
unsr_p, unsr_p, false, NULL);
2800+
flag_trapv = save_flag_trapv;
27842801
return;
27852802
default:
27862803
gcc_unreachable ();
@@ -2826,6 +2843,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
28262843
else
28272844
expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
28282845
uns0_p, uns1_p, false, NULL);
2846+
flag_trapv = save_flag_trapv;
28292847
return;
28302848
}
28312849

gcc/testsuite/gcc.dg/pr114753.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* PR middle-end/114753 */
2+
/* { dg-do run } */
3+
/* { dg-options "-O2 -ftrapv" } */
4+
5+
int
6+
main ()
7+
{
8+
volatile long long i = __LONG_LONG_MAX__;
9+
volatile long long j = 2;
10+
long long k;
11+
if (!__builtin_mul_overflow (i, j, &k) || k != -2LL)
12+
__builtin_abort ();
13+
return 0;
14+
}

0 commit comments

Comments
 (0)