[Flang][Runtime] Handle missing definitions in <cfenv> (#101242)

According to the C99 standard, <fenv.h> may not define FE_INVALID and
the likes. Even if C++11 mandate them, musl and emscripten don't provide
them, so handle that case.
This commit is contained in:
serge-sans-paille 2024-08-21 07:42:18 +00:00 committed by GitHub
parent f47966b1de
commit b6686e764c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 1 deletions

View File

@ -507,18 +507,29 @@ static RT_API_ATTRS void RaiseFPExceptions(
#define RAISE std::feraiseexcept
#endif
#endif // !defined(RT_DEVICE_COMPILATION)
// Some environment (e.g. emscripten, musl) don't define FE_OVERFLOW as allowed
// by c99 (but not c++11) :-/
#if defined(FE_OVERFLOW) || defined(RT_DEVICE_COMPILATION)
if (flags & decimal::ConversionResultFlags::Overflow) {
RAISE(FE_OVERFLOW);
}
#endif
#if defined(FE_UNDERFLOW) || defined(RT_DEVICE_COMPILATION)
if (flags & decimal::ConversionResultFlags::Underflow) {
RAISE(FE_UNDERFLOW);
}
#endif
#if defined(FE_INEXACT) || defined(RT_DEVICE_COMPILATION)
if (flags & decimal::ConversionResultFlags::Inexact) {
RAISE(FE_INEXACT);
}
#endif
#if defined(FE_INVALID) || defined(RT_DEVICE_COMPILATION)
if (flags & decimal::ConversionResultFlags::Invalid) {
RAISE(FE_INVALID);
}
#endif
#undef RAISE
}

View File

@ -12,9 +12,26 @@
#include "terminator.h"
#include <cfenv>
// When not supported, these macro are undefined in cfenv.h,
// set them to zero in that case.
#ifndef FE_INVALID
#define FE_INVALID 0
#endif
#ifndef __FE_DENORM
#define __FE_DENORM 0 // denorm is nonstandard
#endif
#ifndef FE_DIVBYZERO
#define FE_DIVBYZERO 0
#endif
#ifndef FE_OVERFLOW
#define FE_OVERFLOW 0
#endif
#ifndef FE_UNDERFLOW
#define FE_UNDERFLOW 0
#endif
#ifndef FE_INEXACT
#define FE_INEXACT 0
#endif
namespace Fortran::runtime {
@ -45,7 +62,12 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
if (excepts == 0 || excepts >= mapSize) {
terminator.Crash("Invalid excepts value: %d", excepts);
}
return map[excepts];
uint32_t except_value = map[excepts];
if (except_value == 0) {
terminator.Crash(
"Excepts value %d not supported by flang runtime", excepts);
}
return except_value;
}
// Verify that the size of ieee_modes_type and ieee_status_type objects from

View File

@ -26,21 +26,31 @@ static void DescribeIEEESignaledExceptions() {
#endif
if (excepts) {
std::fputs("IEEE arithmetic exceptions signaled:", stderr);
#ifdef FE_DIVBYZERO
if (excepts & FE_DIVBYZERO) {
std::fputs(" DIVBYZERO", stderr);
}
#endif
#ifdef FE_INEXACT
if (excepts & FE_INEXACT) {
std::fputs(" INEXACT", stderr);
}
#endif
#ifdef FE_INVALID
if (excepts & FE_INVALID) {
std::fputs(" INVALID", stderr);
}
#endif
#ifdef FE_OVERFLOW
if (excepts & FE_OVERFLOW) {
std::fputs(" OVERFLOW", stderr);
}
#endif
#ifdef FE_UNDERFLOW
if (excepts & FE_UNDERFLOW) {
std::fputs(" UNDERFLOW", stderr);
}
#endif
std::fputc('\n', stderr);
}
}