From de026aeb8ebb92717ead36bf14bf82356d9b11e1 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Mon, 4 Apr 2022 11:39:51 -0700 Subject: [PATCH] [flang] Raise FP exceptions from runtime conversion to binary Formatted READs of REAL should convert the exception flags from the decimal-to-binary conversion library into real runtime FP exceptions so that they at least show up in the termination message of a STOP statement. Differential Revision: https://reviews.llvm.org/D123714 --- flang/runtime/edit-input.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp index aabe5df30f6d..73a3478fbbe3 100644 --- a/flang/runtime/edit-input.cpp +++ b/flang/runtime/edit-input.cpp @@ -12,6 +12,7 @@ #include "flang/Common/real.h" #include "flang/Common/uint128.h" #include +#include namespace Fortran::runtime::io { @@ -276,6 +277,25 @@ static int ScanRealInput(char *buffer, int bufferSize, IoStatementState &io, return got; } +static void RaiseFPExceptions(decimal::ConversionResultFlags flags) { +#undef RAISE +#ifdef feraisexcept // a macro in some environments; omit std:: +#define RAISE feraiseexcept +#else +#define RAISE std::feraiseexcept +#endif + if (flags & decimal::ConversionResultFlags::Overflow) { + RAISE(FE_OVERFLOW); + } + if (flags & decimal::ConversionResultFlags::Inexact) { + RAISE(FE_INEXACT); + } + if (flags & decimal::ConversionResultFlags::Invalid) { + RAISE(FE_INVALID); + } +#undef RAISE +} + // If no special modes are in effect and the form of the input value // that's present in the input stream is acceptable to the decimal->binary // converter without modification, this fast path for real input @@ -324,10 +344,13 @@ static bool TryFastPathRealInput( return false; // unconverted characters remain in fixed width field } // Success on the fast path! - // TODO: raise converted.flags as exceptions? *reinterpret_cast *>(n) = converted.binary; io.HandleRelativePosition(p - str); + // Set FP exception flags + if (converted.flags != decimal::ConversionResultFlags::Exact) { + RaiseFPExceptions(converted.flags); + } return true; } @@ -395,9 +418,12 @@ bool EditCommonRealInput(IoStatementState &io, const DataEdit &edit, void *n) { converted.flags = static_cast( converted.flags | decimal::Inexact); } - // TODO: raise converted.flags as exceptions? *reinterpret_cast *>(n) = converted.binary; + // Set FP exception flags + if (converted.flags != decimal::ConversionResultFlags::Exact) { + RaiseFPExceptions(converted.flags); + } return true; }