diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h index 6130a25e401c..a1645eb4ef67 100644 --- a/flang/include/flang/Runtime/numeric.h +++ b/flang/include/flang/Runtime/numeric.h @@ -214,48 +214,66 @@ bool RTNAME(IsNaN16)(CppTypeFor); // MOD & MODULO CppTypeFor RTNAME(ModInteger1)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModInteger2)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModInteger4)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModInteger8)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); #ifdef __SIZEOF_INT128__ CppTypeFor RTNAME(ModInteger16)( CppTypeFor, - CppTypeFor); + CppTypeFor, const char *sourceFile = nullptr, + int sourceLine = 0); #endif CppTypeFor RTNAME(ModReal4)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModReal8)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModReal10)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModReal16)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloInteger1)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloInteger2)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloInteger4)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloInteger8)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); #ifdef __SIZEOF_INT128__ CppTypeFor RTNAME(ModuloInteger16)( CppTypeFor, - CppTypeFor); + CppTypeFor, const char *sourceFile = nullptr, + int sourceLine = 0); #endif CppTypeFor RTNAME(ModuloReal4)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloReal8)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloReal10)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); CppTypeFor RTNAME(ModuloReal16)( - CppTypeFor, CppTypeFor); + CppTypeFor, CppTypeFor, + const char *sourceFile = nullptr, int sourceLine = 0); // NINT CppTypeFor RTNAME(Nint4_1)( diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index c04d50111934..4ffb282a87c7 100644 --- a/flang/runtime/numeric.cpp +++ b/flang/runtime/numeric.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "terminator.h" #include "flang/Runtime/numeric.h" #include "flang/Common/long-double.h" #include @@ -62,14 +63,24 @@ template inline T Fraction(T x) { } // MOD & MODULO (16.9.135, .136) -template inline T IntMod(T x, T p) { +template +inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) { + if (p == 0) { + Terminator{sourceFile, sourceLine}.Crash( + IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); + } auto mod{x - (x / p) * p}; if (IS_MODULO && (x > 0) != (p > 0)) { mod += p; } return mod; } -template inline T RealMod(T x, T p) { +template +inline T RealMod(T x, T p, const char *sourceFile, int sourceLine) { + if (p == 0) { + Terminator{sourceFile, sourceLine}.Crash( + IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); + } if constexpr (IS_MODULO) { return x - std::floor(x / p) * p; } else { @@ -542,99 +553,113 @@ bool RTNAME(IsNaN16)(CppTypeFor x) { CppTypeFor RTNAME(ModInteger1)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModInteger2)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModInteger4)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModInteger8)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ CppTypeFor RTNAME(ModInteger16)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTNAME(ModReal4)( - CppTypeFor x, CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModReal8)( - CppTypeFor x, CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #if LONG_DOUBLE == 80 CppTypeFor RTNAME(ModReal10)( - CppTypeFor x, - CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #elif LONG_DOUBLE == 128 CppTypeFor RTNAME(ModReal16)( - CppTypeFor x, - CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTNAME(ModuloInteger1)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModuloInteger2)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModuloInteger4)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModuloInteger8)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ CppTypeFor RTNAME(ModuloInteger16)( CppTypeFor x, - CppTypeFor p) { - return IntMod(x, p); + CppTypeFor p, const char *sourceFile, + int sourceLine) { + return IntMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTNAME(ModuloReal4)( - CppTypeFor x, CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } CppTypeFor RTNAME(ModuloReal8)( - CppTypeFor x, CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #if LONG_DOUBLE == 80 CppTypeFor RTNAME(ModuloReal10)( - CppTypeFor x, - CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #elif LONG_DOUBLE == 128 CppTypeFor RTNAME(ModuloReal16)( - CppTypeFor x, - CppTypeFor p) { - return RealMod(x, p); + CppTypeFor x, CppTypeFor p, + const char *sourceFile, int sourceLine) { + return RealMod(x, p, sourceFile, sourceLine); } #endif