Skip to content

Commit 562fd2c

Browse files
committed
[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
1 parent 11f928a commit 562fd2c

File tree

2 files changed

+103
-60
lines changed

2 files changed

+103
-60
lines changed

flang/include/flang/Runtime/numeric.h

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -214,48 +214,66 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16>);
214214

215215
// MOD & MODULO
216216
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
217-
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
217+
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
218+
const char *sourceFile = nullptr, int sourceLine = 0);
218219
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
219-
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
220+
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
221+
const char *sourceFile = nullptr, int sourceLine = 0);
220222
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
221-
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
223+
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
224+
const char *sourceFile = nullptr, int sourceLine = 0);
222225
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
223-
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
226+
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
227+
const char *sourceFile = nullptr, int sourceLine = 0);
224228
#ifdef __SIZEOF_INT128__
225229
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
226230
CppTypeFor<TypeCategory::Integer, 16>,
227-
CppTypeFor<TypeCategory::Integer, 16>);
231+
CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
232+
int sourceLine = 0);
228233
#endif
229234
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
230-
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
235+
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
236+
const char *sourceFile = nullptr, int sourceLine = 0);
231237
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
232-
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
238+
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
239+
const char *sourceFile = nullptr, int sourceLine = 0);
233240
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
234-
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
241+
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
242+
const char *sourceFile = nullptr, int sourceLine = 0);
235243
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
236-
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
244+
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
245+
const char *sourceFile = nullptr, int sourceLine = 0);
237246

238247
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
239-
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
248+
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
249+
const char *sourceFile = nullptr, int sourceLine = 0);
240250
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
241-
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
251+
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>,
252+
const char *sourceFile = nullptr, int sourceLine = 0);
242253
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
243-
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
254+
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>,
255+
const char *sourceFile = nullptr, int sourceLine = 0);
244256
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
245-
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
257+
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>,
258+
const char *sourceFile = nullptr, int sourceLine = 0);
246259
#ifdef __SIZEOF_INT128__
247260
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
248261
CppTypeFor<TypeCategory::Integer, 16>,
249-
CppTypeFor<TypeCategory::Integer, 16>);
262+
CppTypeFor<TypeCategory::Integer, 16>, const char *sourceFile = nullptr,
263+
int sourceLine = 0);
250264
#endif
251265
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
252-
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
266+
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>,
267+
const char *sourceFile = nullptr, int sourceLine = 0);
253268
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
254-
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
269+
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
270+
const char *sourceFile = nullptr, int sourceLine = 0);
255271
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
256-
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
272+
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
273+
const char *sourceFile = nullptr, int sourceLine = 0);
257274
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
258-
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
275+
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
276+
const char *sourceFile = nullptr, int sourceLine = 0);
259277

260278
// NINT
261279
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(

flang/runtime/numeric.cpp

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "terminator.h"
910
#include "flang/Runtime/numeric.h"
1011
#include "flang/Common/long-double.h"
1112
#include <climits>
@@ -62,14 +63,24 @@ template <typename T> inline T Fraction(T x) {
6263
}
6364

6465
// MOD & MODULO (16.9.135, .136)
65-
template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) {
66+
template <bool IS_MODULO, typename T>
67+
inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) {
68+
if (p == 0) {
69+
Terminator{sourceFile, sourceLine}.Crash(
70+
IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
71+
}
6672
auto mod{x - (x / p) * p};
6773
if (IS_MODULO && (x > 0) != (p > 0)) {
6874
mod += p;
6975
}
7076
return mod;
7177
}
72-
template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) {
78+
template <bool IS_MODULO, typename T>
79+
inline T RealMod(T x, T p, const char *sourceFile, int sourceLine) {
80+
if (p == 0) {
81+
Terminator{sourceFile, sourceLine}.Crash(
82+
IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
83+
}
7384
if constexpr (IS_MODULO) {
7485
return x - std::floor(x / p) * p;
7586
} else {
@@ -542,99 +553,113 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
542553

543554
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
544555
CppTypeFor<TypeCategory::Integer, 1> x,
545-
CppTypeFor<TypeCategory::Integer, 1> p) {
546-
return IntMod<false>(x, p);
556+
CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
557+
int sourceLine) {
558+
return IntMod<false>(x, p, sourceFile, sourceLine);
547559
}
548560
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
549561
CppTypeFor<TypeCategory::Integer, 2> x,
550-
CppTypeFor<TypeCategory::Integer, 2> p) {
551-
return IntMod<false>(x, p);
562+
CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
563+
int sourceLine) {
564+
return IntMod<false>(x, p, sourceFile, sourceLine);
552565
}
553566
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
554567
CppTypeFor<TypeCategory::Integer, 4> x,
555-
CppTypeFor<TypeCategory::Integer, 4> p) {
556-
return IntMod<false>(x, p);
568+
CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
569+
int sourceLine) {
570+
return IntMod<false>(x, p, sourceFile, sourceLine);
557571
}
558572
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
559573
CppTypeFor<TypeCategory::Integer, 8> x,
560-
CppTypeFor<TypeCategory::Integer, 8> p) {
561-
return IntMod<false>(x, p);
574+
CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
575+
int sourceLine) {
576+
return IntMod<false>(x, p, sourceFile, sourceLine);
562577
}
563578
#ifdef __SIZEOF_INT128__
564579
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
565580
CppTypeFor<TypeCategory::Integer, 16> x,
566-
CppTypeFor<TypeCategory::Integer, 16> p) {
567-
return IntMod<false>(x, p);
581+
CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
582+
int sourceLine) {
583+
return IntMod<false>(x, p, sourceFile, sourceLine);
568584
}
569585
#endif
570586
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
571-
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
572-
return RealMod<false>(x, p);
587+
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
588+
const char *sourceFile, int sourceLine) {
589+
return RealMod<false>(x, p, sourceFile, sourceLine);
573590
}
574591
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
575-
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
576-
return RealMod<false>(x, p);
592+
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
593+
const char *sourceFile, int sourceLine) {
594+
return RealMod<false>(x, p, sourceFile, sourceLine);
577595
}
578596
#if LONG_DOUBLE == 80
579597
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
580-
CppTypeFor<TypeCategory::Real, 10> x,
581-
CppTypeFor<TypeCategory::Real, 10> p) {
582-
return RealMod<false>(x, p);
598+
CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
599+
const char *sourceFile, int sourceLine) {
600+
return RealMod<false>(x, p, sourceFile, sourceLine);
583601
}
584602
#elif LONG_DOUBLE == 128
585603
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
586-
CppTypeFor<TypeCategory::Real, 16> x,
587-
CppTypeFor<TypeCategory::Real, 16> p) {
588-
return RealMod<false>(x, p);
604+
CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
605+
const char *sourceFile, int sourceLine) {
606+
return RealMod<false>(x, p, sourceFile, sourceLine);
589607
}
590608
#endif
591609

592610
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
593611
CppTypeFor<TypeCategory::Integer, 1> x,
594-
CppTypeFor<TypeCategory::Integer, 1> p) {
595-
return IntMod<true>(x, p);
612+
CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
613+
int sourceLine) {
614+
return IntMod<true>(x, p, sourceFile, sourceLine);
596615
}
597616
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
598617
CppTypeFor<TypeCategory::Integer, 2> x,
599-
CppTypeFor<TypeCategory::Integer, 2> p) {
600-
return IntMod<true>(x, p);
618+
CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
619+
int sourceLine) {
620+
return IntMod<true>(x, p, sourceFile, sourceLine);
601621
}
602622
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
603623
CppTypeFor<TypeCategory::Integer, 4> x,
604-
CppTypeFor<TypeCategory::Integer, 4> p) {
605-
return IntMod<true>(x, p);
624+
CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
625+
int sourceLine) {
626+
return IntMod<true>(x, p, sourceFile, sourceLine);
606627
}
607628
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
608629
CppTypeFor<TypeCategory::Integer, 8> x,
609-
CppTypeFor<TypeCategory::Integer, 8> p) {
610-
return IntMod<true>(x, p);
630+
CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
631+
int sourceLine) {
632+
return IntMod<true>(x, p, sourceFile, sourceLine);
611633
}
612634
#ifdef __SIZEOF_INT128__
613635
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
614636
CppTypeFor<TypeCategory::Integer, 16> x,
615-
CppTypeFor<TypeCategory::Integer, 16> p) {
616-
return IntMod<true>(x, p);
637+
CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
638+
int sourceLine) {
639+
return IntMod<true>(x, p, sourceFile, sourceLine);
617640
}
618641
#endif
619642
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
620-
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
621-
return RealMod<true>(x, p);
643+
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
644+
const char *sourceFile, int sourceLine) {
645+
return RealMod<true>(x, p, sourceFile, sourceLine);
622646
}
623647
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
624-
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
625-
return RealMod<true>(x, p);
648+
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
649+
const char *sourceFile, int sourceLine) {
650+
return RealMod<true>(x, p, sourceFile, sourceLine);
626651
}
627652
#if LONG_DOUBLE == 80
628653
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
629-
CppTypeFor<TypeCategory::Real, 10> x,
630-
CppTypeFor<TypeCategory::Real, 10> p) {
631-
return RealMod<true>(x, p);
654+
CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
655+
const char *sourceFile, int sourceLine) {
656+
return RealMod<true>(x, p, sourceFile, sourceLine);
632657
}
633658
#elif LONG_DOUBLE == 128
634659
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
635-
CppTypeFor<TypeCategory::Real, 16> x,
636-
CppTypeFor<TypeCategory::Real, 16> p) {
637-
return RealMod<true>(x, p);
660+
CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
661+
const char *sourceFile, int sourceLine) {
662+
return RealMod<true>(x, p, sourceFile, sourceLine);
638663
}
639664
#endif
640665

0 commit comments

Comments
 (0)