@@ -303,41 +303,72 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
303
303
context, std::move (funcRef), RelationalOperator::LT, T::Scalar::HUGE ());
304
304
} else if (name == " mod" ) {
305
305
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
+ }
306
317
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
+ }));
318
329
} else if (name == " modulo" ) {
319
330
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
+ }
320
342
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
+ }));
332
354
} 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 ));
334
357
return common::visit (
335
358
[&](const auto &sVal ) {
336
359
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
+ }
337
368
return FoldElementalIntrinsic<T, T, TS>(context, std::move (funcRef),
338
369
ScalarFunc<T, T, TS>([&](const Scalar<T> &x,
339
370
const Scalar<TS> &s) -> Scalar<T> {
340
- if (s.IsZero () &&
371
+ if (!badSConst && s.IsZero () &&
341
372
context.languageFeatures ().ShouldWarn (
342
373
common::UsageWarning::FoldingValueChecks)) {
343
374
context.messages ().Say (
0 commit comments