@@ -303,41 +303,72 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
303303 context, std::move (funcRef), RelationalOperator::LT, T::Scalar::HUGE ());
304304 } else if (name == " mod" ) {
305305 CHECK (args.size () == 2 );
306+ bool badPConst{false };
307+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1 ])}) {
308+ *pExpr = Fold (context, std::move (*pExpr));
309+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
310+ pConst->IsZero () &&
311+ context.languageFeatures ().ShouldWarn (
312+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
313+ context.messages ().Say (" MOD: P argument is zero" _warn_en_US);
314+ badPConst = true ;
315+ }
316+ }
306317 return FoldElementalIntrinsic<T, T, T>(context, std::move (funcRef),
307- ScalarFunc<T, T, T>(
308- [&context]( const Scalar<T> &x, const Scalar<T> &y) -> Scalar<T> {
309- auto result{x.MOD (y)};
310- if (result.flags .test (RealFlag::DivideByZero) &&
311- context.languageFeatures ().ShouldWarn (
312- common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
313- context.messages ().Say (
314- " second argument to MOD must not be zero" _warn_en_US);
315- }
316- return result.value ;
317- }));
318+ ScalarFunc<T, T, T>([&context, badPConst]( const Scalar<T> &x,
319+ const Scalar<T> &y) -> Scalar<T> {
320+ auto result{x.MOD (y)};
321+ if (!badPConst && result.flags .test (RealFlag::DivideByZero) &&
322+ context.languageFeatures ().ShouldWarn (
323+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
324+ context.messages ().Say (
325+ " second argument to MOD must not be zero" _warn_en_US);
326+ }
327+ return result.value ;
328+ }));
318329 } else if (name == " modulo" ) {
319330 CHECK (args.size () == 2 );
331+ bool badPConst{false };
332+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1 ])}) {
333+ *pExpr = Fold (context, std::move (*pExpr));
334+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
335+ pConst->IsZero () &&
336+ context.languageFeatures ().ShouldWarn (
337+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
338+ context.messages ().Say (" MODULO: P argument is zero" _warn_en_US);
339+ badPConst = true ;
340+ }
341+ }
320342 return FoldElementalIntrinsic<T, T, T>(context, std::move (funcRef),
321- ScalarFunc<T, T, T>(
322- [&context]( const Scalar<T> &x, const Scalar<T> &y) -> Scalar<T> {
323- auto result{x.MODULO (y)};
324- if (result.flags .test (RealFlag::DivideByZero) &&
325- context.languageFeatures ().ShouldWarn (
326- common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
327- context.messages ().Say (
328- " second argument to MODULO must not be zero" _warn_en_US);
329- }
330- return result.value ;
331- }));
343+ ScalarFunc<T, T, T>([&context, badPConst]( const Scalar<T> &x,
344+ const Scalar<T> &y) -> Scalar<T> {
345+ auto result{x.MODULO (y)};
346+ if (!badPConst && result.flags .test (RealFlag::DivideByZero) &&
347+ context.languageFeatures ().ShouldWarn (
348+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
349+ context.messages ().Say (
350+ " second argument to MODULO must not be zero" _warn_en_US);
351+ }
352+ return result.value ;
353+ }));
332354 } else if (name == " nearest" ) {
333- if (const auto *sExpr {UnwrapExpr<Expr<SomeReal>>(args[1 ])}) {
355+ if (auto *sExpr {UnwrapExpr<Expr<SomeReal>>(args[1 ])}) {
356+ *sExpr = Fold (context, std::move (*sExpr ));
334357 return common::visit (
335358 [&](const auto &sVal ) {
336359 using TS = ResultType<decltype (sVal )>;
360+ bool badSConst{false };
361+ if (auto sConst {GetScalarConstantValue<TS>(sVal )}; sConst &&
362+ sConst ->IsZero () &&
363+ context.languageFeatures ().ShouldWarn (
364+ common::UsageWarning::FoldingValueChecks)) {
365+ context.messages ().Say (" NEAREST: S argument is zero" _warn_en_US);
366+ badSConst = true ;
367+ }
337368 return FoldElementalIntrinsic<T, T, TS>(context, std::move (funcRef),
338369 ScalarFunc<T, T, TS>([&](const Scalar<T> &x,
339370 const Scalar<TS> &s) -> Scalar<T> {
340- if (s.IsZero () &&
371+ if (!badSConst && s.IsZero () &&
341372 context.languageFeatures ().ShouldWarn (
342373 common::UsageWarning::FoldingValueChecks)) {
343374 context.messages ().Say (
0 commit comments