https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105973
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- If the two noreturn functions are replaced with throwing exceptions, I get the behaviour I expect: if (n > (__PTRDIFF_MAX__ / sizeof(T))) { if (n > (__SIZE_MAX__ / sizeof(T))) throw 1; throw 2L; } This is correctly treated as unlikely. So the problem only seems to happen because of libstdc++'s convention of using named noreturn functions to throw exceptions (which is done to simplify -fno-exceptions cases). This probably doesn't affect much user code. It also seem that if I explicitly add the 'cold' attribute to those noreturn functions, I get the behaviour I expect. So maybe it's not worth spending any effort on this, and I should just change __attribute__((__noreturn__)) to __attribute__((__noreturn__,__cold)) for every function in libstdc++-v3/include/bits/functexcept.h