fix(libc): fmod leaves errno unchanged

fmod set errno (33) for 1.0, 0.0. FreeBSD msun never sets errno and
reports errors through floating-point exceptions only, so errno is now
saved and restored around the host call.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
Alex 2026-10-11 10:07:19 -04:00
parent a11c8f7f70
commit 632338cd65
2 changed files with 15 additions and 1 deletions

View File

@ -127,7 +127,12 @@ float APS5_VABI logf_nid_postfix(float x) { return std::log(x); }
float APS5_VABI log2f_nid_postfix(float x) { return std::log2(x); }
double APS5_VABI log10_nid_postfix(double x) { return std::log10(x); }
float APS5_VABI ldexpf_nid_postfix(float x, int exp) { return std::ldexp(x, exp); }
double APS5_VABI fmod_nid_postfix(double x, double y) { return std::fmod(x, y); }
double APS5_VABI fmod_nid_postfix(double x, double y) {
int saved_errno = errno;
double result = std::fmod(x, y);
errno = saved_errno;
return result;
}
float APS5_VABI roundf_nid_postfix(float x) { return std::round(x); }
double APS5_VABI round_nid_postfix(double x) { return std::round(x); }
float APS5_VABI cbrtf_nid_postfix(float x) { return std::cbrt(x); }

View File

@ -38,6 +38,7 @@ extern LibcFloatConstant _FNan_nid_postfix;
short APS5_VABI _FDtest_nid_postfix(const float*);
int APS5_VABI __fpclassifyf_nid_postfix(float);
float APS5_VABI fmodf_nid_postfix(float, float);
double APS5_VABI fmod_nid_postfix(double, double);
float APS5_VABI asinf_nid_postfix(float);
float APS5_VABI acosf_nid_postfix(float);
float APS5_VABI atan2f_nid_postfix(float, float);
@ -150,6 +151,13 @@ static void CheckLongDouble() {
Require(std::isnan(frexpl_nid_postfix(NAN, &exponent)) && exponent == 77);
}
static void CheckFmodErrno() {
errno = 0;
(void)fmod_nid_postfix(1.0, 0.0);
Require(errno == 0);
Require(fmod_nid_postfix(1e300, 3.0) == std::fmod(1e300, 3.0));
}
static void CheckIntegerConversions() {
for (const long long numerator : {4294967301LL, -4294967301LL}) {
for (const long long denominator : {3LL, -3LL}) {
@ -493,4 +501,5 @@ int main() {
Require(abs_nid_postfix(std::numeric_limits<int>::min()) == std::numeric_limits<int>::min());
CheckHyperbolic();
CheckHypotSpecialValue();
CheckFmodErrno();
}