https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108481
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Known to work|12.2.0 | Summary|[13 Regression] UBsan |[10/11/12/13 Regression] |missed a signed integer |UBsan missed a signed |overflow |integer overflow Keywords|needs-bisection | --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Why is this marked 13 Regression? I can certainly reproduce up to ~ r260000, with just -O1 -fsanitize=signed-integer-overflow so that I can use newer libubsan for even older code back to r8-93-g2700fbd655f608e8e23. The difference with r8-93 from earlier commits is that we decide to sink the i_15 = UBSAN_CHECK_SUB (i_9, 6822162149299574294); statement, because the result of i isn't really used in the path when j == 0. We intentionally mark UBSAN_CHECK_SUB etc. internal functions as ECF_CONST, so that they can be DCEd etc., we don't want to kill performance with -fsanitize=undefined, if you don't care about performance of the code, just use -O0 with -fsanitize=undefined. So, similarly to how we don't diagnose long foo (long i) { i = i - 6822162149299574294; return 0; } int main () { return foo (-5354944485355449974); } at -O2 because the result of the subtraction isn't used, we allow the i = i - 6822162149299574294; subtraction to be sunk, so effectively: @@ -11,8 +11,8 @@ static char f(int *g, short h, long i) { if ((i * (unsigned long)7 <= 1) << j) ; else { - i = i - 6822162149299574294; if (j) { + i = i - 6822162149299574294; if (*g) break; continue; change in the source because for the return 8; path nothing cares about the result. I'd say this behaves as designed.