Skip to content

Commit b6686e7

Browse files
[Flang][Runtime] Handle missing definitions in <cfenv> (llvm#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.
1 parent f47966b commit b6686e7

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

flang/runtime/edit-input.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -507,18 +507,29 @@ static RT_API_ATTRS void RaiseFPExceptions(
507507
#define RAISE std::feraiseexcept
508508
#endif
509509
#endif // !defined(RT_DEVICE_COMPILATION)
510+
511+
// Some environment (e.g. emscripten, musl) don't define FE_OVERFLOW as allowed
512+
// by c99 (but not c++11) :-/
513+
#if defined(FE_OVERFLOW) || defined(RT_DEVICE_COMPILATION)
510514
if (flags & decimal::ConversionResultFlags::Overflow) {
511515
RAISE(FE_OVERFLOW);
512516
}
517+
#endif
518+
#if defined(FE_UNDERFLOW) || defined(RT_DEVICE_COMPILATION)
513519
if (flags & decimal::ConversionResultFlags::Underflow) {
514520
RAISE(FE_UNDERFLOW);
515521
}
522+
#endif
523+
#if defined(FE_INEXACT) || defined(RT_DEVICE_COMPILATION)
516524
if (flags & decimal::ConversionResultFlags::Inexact) {
517525
RAISE(FE_INEXACT);
518526
}
527+
#endif
528+
#if defined(FE_INVALID) || defined(RT_DEVICE_COMPILATION)
519529
if (flags & decimal::ConversionResultFlags::Invalid) {
520530
RAISE(FE_INVALID);
521531
}
532+
#endif
522533
#undef RAISE
523534
}
524535

flang/runtime/exceptions.cpp

+23-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,26 @@
1212
#include "terminator.h"
1313
#include <cfenv>
1414

15+
// When not supported, these macro are undefined in cfenv.h,
16+
// set them to zero in that case.
17+
#ifndef FE_INVALID
18+
#define FE_INVALID 0
19+
#endif
1520
#ifndef __FE_DENORM
1621
#define __FE_DENORM 0 // denorm is nonstandard
1722
#endif
23+
#ifndef FE_DIVBYZERO
24+
#define FE_DIVBYZERO 0
25+
#endif
26+
#ifndef FE_OVERFLOW
27+
#define FE_OVERFLOW 0
28+
#endif
29+
#ifndef FE_UNDERFLOW
30+
#define FE_UNDERFLOW 0
31+
#endif
32+
#ifndef FE_INEXACT
33+
#define FE_INEXACT 0
34+
#endif
1835

1936
namespace Fortran::runtime {
2037

@@ -45,7 +62,12 @@ uint32_t RTNAME(MapException)(uint32_t excepts) {
4562
if (excepts == 0 || excepts >= mapSize) {
4663
terminator.Crash("Invalid excepts value: %d", excepts);
4764
}
48-
return map[excepts];
65+
uint32_t except_value = map[excepts];
66+
if (except_value == 0) {
67+
terminator.Crash(
68+
"Excepts value %d not supported by flang runtime", excepts);
69+
}
70+
return except_value;
4971
}
5072

5173
// Verify that the size of ieee_modes_type and ieee_status_type objects from

flang/runtime/stop.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,31 @@ static void DescribeIEEESignaledExceptions() {
2626
#endif
2727
if (excepts) {
2828
std::fputs("IEEE arithmetic exceptions signaled:", stderr);
29+
#ifdef FE_DIVBYZERO
2930
if (excepts & FE_DIVBYZERO) {
3031
std::fputs(" DIVBYZERO", stderr);
3132
}
33+
#endif
34+
#ifdef FE_INEXACT
3235
if (excepts & FE_INEXACT) {
3336
std::fputs(" INEXACT", stderr);
3437
}
38+
#endif
39+
#ifdef FE_INVALID
3540
if (excepts & FE_INVALID) {
3641
std::fputs(" INVALID", stderr);
3742
}
43+
#endif
44+
#ifdef FE_OVERFLOW
3845
if (excepts & FE_OVERFLOW) {
3946
std::fputs(" OVERFLOW", stderr);
4047
}
48+
#endif
49+
#ifdef FE_UNDERFLOW
4150
if (excepts & FE_UNDERFLOW) {
4251
std::fputs(" UNDERFLOW", stderr);
4352
}
53+
#endif
4454
std::fputc('\n', stderr);
4555
}
4656
}

0 commit comments

Comments
 (0)