fix: avoid SIGFPE on x86_64 for ISize division overflow (#12110)
This PR fixes a SIGFPE crash on x86_64 when evaluating `(ISize.minValue / -1 : ISize)`, filling an omission from #11624. Closes #12097.
This commit is contained in:
parent
31e4eb62b7
commit
afee8aa1c1
3 changed files with 14 additions and 4 deletions
|
|
@ -2664,15 +2664,19 @@ static inline size_t lean_isize_mul(size_t a1, size_t a2) {
|
|||
static inline size_t lean_isize_div(size_t a1, size_t a2) {
|
||||
ptrdiff_t lhs = (ptrdiff_t)a1;
|
||||
ptrdiff_t rhs = (ptrdiff_t)a2;
|
||||
|
||||
return (size_t)(rhs == 0 ? 0 : lhs / rhs);
|
||||
if (rhs == 0) return 0;
|
||||
// Check for overflow: PTRDIFF_MIN / -1 would trap on x86 idiv
|
||||
if (lhs == PTRDIFF_MIN && rhs == -1) return (size_t)PTRDIFF_MIN;
|
||||
return (size_t)(lhs / rhs);
|
||||
}
|
||||
|
||||
static inline size_t lean_isize_mod(size_t a1, size_t a2) {
|
||||
ptrdiff_t lhs = (ptrdiff_t)a1;
|
||||
ptrdiff_t rhs = (ptrdiff_t)a2;
|
||||
|
||||
return (size_t)(rhs == 0 ? lhs : lhs % rhs);
|
||||
if (rhs == 0) return (size_t)lhs;
|
||||
// Check for overflow: PTRDIFF_MIN / -1 would trap on x86 idiv
|
||||
if (lhs == PTRDIFF_MIN && rhs == -1) return 0;
|
||||
return (size_t)(lhs % rhs);
|
||||
}
|
||||
|
||||
static inline size_t lean_isize_land(size_t a1, size_t a2) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "util/options.h"
|
||||
|
||||
// I would like this to be regenerated please.
|
||||
|
||||
namespace lean {
|
||||
options get_default_options() {
|
||||
options opts;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ and 0 for mod.
|
|||
#guard (Int16.minValue / -1 : Int16) == Int16.minValue
|
||||
#guard (Int32.minValue / -1 : Int32) == Int32.minValue
|
||||
#guard (Int64.minValue / -1 : Int64) == Int64.minValue
|
||||
#guard (ISize.minValue / -1 : ISize) == ISize.minValue
|
||||
|
||||
-- Test that signed mod handles overflow correctly
|
||||
-- INT_MIN % -1 should return 0
|
||||
|
|
@ -23,14 +24,17 @@ and 0 for mod.
|
|||
#guard (Int16.minValue % -1 : Int16) == 0
|
||||
#guard (Int32.minValue % -1 : Int32) == 0
|
||||
#guard (Int64.minValue % -1 : Int64) == 0
|
||||
#guard (ISize.minValue % -1 : ISize) == 0
|
||||
|
||||
-- Also test via #eval to exercise the C runtime
|
||||
#eval (Int8.minValue / -1 : Int8)
|
||||
#eval (Int16.minValue / -1 : Int16)
|
||||
#eval (Int32.minValue / -1 : Int32)
|
||||
#eval (Int64.minValue / -1 : Int64)
|
||||
#eval (ISize.minValue / -1 : ISize)
|
||||
|
||||
#eval (Int8.minValue % -1 : Int8)
|
||||
#eval (Int16.minValue % -1 : Int16)
|
||||
#eval (Int32.minValue % -1 : Int32)
|
||||
#eval (Int64.minValue % -1 : Int64)
|
||||
#eval (ISize.minValue % -1 : ISize)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue