From 9f8ee610beb18930e2ad8461cf5105bcdb5a4fec Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 3 Feb 2023 17:19:55 -0800 Subject: [PATCH] [flang] Warn on overflow folding DIM() The intrinsic function DIM can overflow when its second argument is negative. Detect this case for real and integer arguments and emit a warning when necessary. Differential Revision: https://reviews.llvm.org/D143798 --- flang/include/flang/Evaluate/integer.h | 6 +++--- flang/lib/Evaluate/fold-integer.cpp | 11 +++++++++-- flang/lib/Evaluate/fold-real.cpp | 12 ++++++++---- flang/test/Evaluate/errors01.f90 | 4 ++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/flang/include/flang/Evaluate/integer.h b/flang/include/flang/Evaluate/integer.h index 6a129bf..2fce4be 100644 --- a/flang/include/flang/Evaluate/integer.h +++ b/flang/include/flang/Evaluate/integer.h @@ -784,12 +784,12 @@ public: return {diff.value, overflow}; } - // MAX(X-Y, 0) - constexpr Integer DIM(const Integer &y) const { + // DIM(X,Y)=MAX(X-Y, 0) + constexpr ValueWithOverflow DIM(const Integer &y) const { if (CompareSigned(y) != Ordering::Greater) { return {}; } else { - return SubtractSigned(y).value; + return SubtractSigned(y); } } diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp index 61e76b5..cd8e8f5 100644 --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -568,8 +568,15 @@ Expr> FoldIntrinsicFunction( cx->u)}; } } else if (name == "dim") { - return FoldElementalIntrinsic( - context, std::move(funcRef), &Scalar::DIM); + return FoldElementalIntrinsic(context, std::move(funcRef), + ScalarFunc([&context](const Scalar &x, + const Scalar &y) -> Scalar { + auto result{x.DIM(y)}; + if (result.overflow) { + context.messages().Say("DIM intrinsic folding overflow"_warn_en_US); + } + return result.value; + })); } else if (name == "dot_product") { return FoldDotProduct(context, std::move(funcRef)); } else if (name == "dshiftl" || name == "dshiftr") { diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp index ef90d12..196fdaf 100644 --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -138,10 +138,14 @@ Expr> FoldIntrinsicFunction( })); } else if (name == "dim") { return FoldElementalIntrinsic(context, std::move(funcRef), - ScalarFunc( - [](const Scalar &x, const Scalar &y) -> Scalar { - return x.DIM(y).value; - })); + ScalarFunc([&context](const Scalar &x, + const Scalar &y) -> Scalar { + ValueWithRealFlags> result{x.DIM(y)}; + if (result.flags.test(RealFlag::Overflow)) { + context.messages().Say("DIM intrinsic folding overflow"_warn_en_US); + } + return result.value; + })); } else if (name == "dot_product") { return FoldDotProduct(context, std::move(funcRef)); } else if (name == "dprod") { diff --git a/flang/test/Evaluate/errors01.f90 b/flang/test/Evaluate/errors01.f90 index 14702cc..46cc4e6 100644 --- a/flang/test/Evaluate/errors01.f90 +++ b/flang/test/Evaluate/errors01.f90 @@ -156,6 +156,10 @@ module m real, parameter :: bad1 = scale(1.0, 99999) !CHECK: complex ABS intrinsic folding overflow real, parameter :: bad2 = abs(cmplx(huge(0.),huge(0.))) + !CHECK: warning: DIM intrinsic folding overflow + real, parameter :: bad3 = dim(huge(1.),-.5*huge(1.)) + !CHECK: warning: DIM intrinsic folding overflow + integer, parameter :: bad4 = dim(huge(1),-1) !CHECK: warning: overflow on REAL(8) to REAL(4) conversion x = 1.D40 end subroutine -- 2.7.4