[flang-commits] [flang] 562fd2c - [flang][runtime] Emit error message rather than crashing for MOD(ULO)(x, P=0)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Jun 4 11:06:16 PDT 2022


Author: Peter Klausler
Date: 2022-06-04T11:02:48-07:00
New Revision: 562fd2c99b70691affe7776a1900e95ee7da0b3b

URL: https://github.com/llvm/llvm-project/commit/562fd2c99b70691affe7776a1900e95ee7da0b3b
DIFF: https://github.com/llvm/llvm-project/commit/562fd2c99b70691affe7776a1900e95ee7da0b3b.diff

LOG: [flang][runtime] Emit error message rather than crashing for MOD(ULO)(x,P=0)

Add extra arguments and checks to the runtime support library so that
a call to the intrinsic functions MOD and MODULO with "denominator"
argument P of zero will cause a crash with a source location rather
than an uninformative floating-point error or integer division by
zero signal.

Additional work is required in lowering to (1) pass source file path and
source line number arguments and (2) actually call these runtime
library APIs instead of emitting inline code for MOD &/or MODULO.

Differential Revision: https://reviews.llvm.org/D127034

Added: 
    

Modified: 
    flang/include/flang/Runtime/numeric.h
    flang/runtime/numeric.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index 6130a25e401c3..a1645eb4ef675 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -214,48 +214,66 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16>);
 
 // MOD & MODULO
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
-    CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
+    CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
-    CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
+    CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
-    CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
+    CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
-    CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
+    CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 #ifdef __SIZEOF_INT128__
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
     CppTypeFor<TypeCategory::Integer, 16>,
-    CppTypeFor<TypeCategory::Integer, 16>);
+    CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
+    int sourceLine = 0);
 #endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
-    CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
+    CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
-    CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
+    CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
-    CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
+    CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
-    CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
+    CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
-    CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
+    CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
-    CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
+    CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
-    CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
+    CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
-    CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
+    CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 #ifdef __SIZEOF_INT128__
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
     CppTypeFor<TypeCategory::Integer, 16>,
-    CppTypeFor<TypeCategory::Integer, 16>);
+    CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
+    int sourceLine = 0);
 #endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
-    CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
+    CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
-    CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
+    CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
-    CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
+    CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
-    CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
+    CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
+    const char *sourceFile = nullptr, int sourceLine = 0);
 
 // NINT
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(

diff  --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index c04d50111934b..4ffb282a87c77 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 <climits>
@@ -62,14 +63,24 @@ template <typename T> inline T Fraction(T x) {
 }
 
 // MOD & MODULO (16.9.135, .136)
-template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) {
+template <bool IS_MODULO, typename T>
+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 <bool IS_MODULO, typename T> inline T RealMod(T x, T p) {
+template <bool IS_MODULO, typename T>
+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<TypeCategory::Real, 16> x) {
 
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
     CppTypeFor<TypeCategory::Integer, 1> x,
-    CppTypeFor<TypeCategory::Integer, 1> p) {
-  return IntMod<false>(x, p);
+    CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<false>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
     CppTypeFor<TypeCategory::Integer, 2> x,
-    CppTypeFor<TypeCategory::Integer, 2> p) {
-  return IntMod<false>(x, p);
+    CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<false>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
     CppTypeFor<TypeCategory::Integer, 4> x,
-    CppTypeFor<TypeCategory::Integer, 4> p) {
-  return IntMod<false>(x, p);
+    CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<false>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
     CppTypeFor<TypeCategory::Integer, 8> x,
-    CppTypeFor<TypeCategory::Integer, 8> p) {
-  return IntMod<false>(x, p);
+    CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<false>(x, p, sourceFile, sourceLine);
 }
 #ifdef __SIZEOF_INT128__
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
     CppTypeFor<TypeCategory::Integer, 16> x,
-    CppTypeFor<TypeCategory::Integer, 16> p) {
-  return IntMod<false>(x, p);
+    CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<false>(x, p, sourceFile, sourceLine);
 }
 #endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
-    CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
-  return RealMod<false>(x, p);
+    CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<false>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
-    CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
-  return RealMod<false>(x, p);
+    CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<false>(x, p, sourceFile, sourceLine);
 }
 #if LONG_DOUBLE == 80
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
-    CppTypeFor<TypeCategory::Real, 10> x,
-    CppTypeFor<TypeCategory::Real, 10> p) {
-  return RealMod<false>(x, p);
+    CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<false>(x, p, sourceFile, sourceLine);
 }
 #elif LONG_DOUBLE == 128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
-    CppTypeFor<TypeCategory::Real, 16> x,
-    CppTypeFor<TypeCategory::Real, 16> p) {
-  return RealMod<false>(x, p);
+    CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<false>(x, p, sourceFile, sourceLine);
 }
 #endif
 
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
     CppTypeFor<TypeCategory::Integer, 1> x,
-    CppTypeFor<TypeCategory::Integer, 1> p) {
-  return IntMod<true>(x, p);
+    CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<true>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
     CppTypeFor<TypeCategory::Integer, 2> x,
-    CppTypeFor<TypeCategory::Integer, 2> p) {
-  return IntMod<true>(x, p);
+    CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<true>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
     CppTypeFor<TypeCategory::Integer, 4> x,
-    CppTypeFor<TypeCategory::Integer, 4> p) {
-  return IntMod<true>(x, p);
+    CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<true>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
     CppTypeFor<TypeCategory::Integer, 8> x,
-    CppTypeFor<TypeCategory::Integer, 8> p) {
-  return IntMod<true>(x, p);
+    CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<true>(x, p, sourceFile, sourceLine);
 }
 #ifdef __SIZEOF_INT128__
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
     CppTypeFor<TypeCategory::Integer, 16> x,
-    CppTypeFor<TypeCategory::Integer, 16> p) {
-  return IntMod<true>(x, p);
+    CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
+    int sourceLine) {
+  return IntMod<true>(x, p, sourceFile, sourceLine);
 }
 #endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
-    CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
-  return RealMod<true>(x, p);
+    CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<true>(x, p, sourceFile, sourceLine);
 }
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
-    CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
-  return RealMod<true>(x, p);
+    CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<true>(x, p, sourceFile, sourceLine);
 }
 #if LONG_DOUBLE == 80
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
-    CppTypeFor<TypeCategory::Real, 10> x,
-    CppTypeFor<TypeCategory::Real, 10> p) {
-  return RealMod<true>(x, p);
+    CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<true>(x, p, sourceFile, sourceLine);
 }
 #elif LONG_DOUBLE == 128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
-    CppTypeFor<TypeCategory::Real, 16> x,
-    CppTypeFor<TypeCategory::Real, 16> p) {
-  return RealMod<true>(x, p);
+    CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
+    const char *sourceFile, int sourceLine) {
+  return RealMod<true>(x, p, sourceFile, sourceLine);
 }
 #endif
 


        


More information about the flang-commits mailing list