@@ -352,30 +352,30 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
352
352
} else if (name == " iany" ) {
353
353
return FoldBitReduction (
354
354
context, std::move (funcRef), &Scalar<T>::IOR, Scalar<T>{});
355
- } else if (name == " ibclr" || name == " ibset" || name == " ishft" ||
356
- name == " shifta" || name == " shiftr" || name == " shiftl" ) {
357
- // Second argument can be of any kind. However, it must be smaller or
358
- // equal than BIT_SIZE. It can be converted to Int4 to simplify.
355
+ } else if (name == " ibclr" || name == " ibset" ) {
356
+ // Second argument can be of any kind. However, it must be smaller
357
+ // than BIT_SIZE. It can be converted to Int4 to simplify.
359
358
auto fptr{&Scalar<T>::IBCLR};
360
- if (name == " ibclr" ) { // done in fprt definition
359
+ if (name == " ibclr" ) { // done in fptr definition
361
360
} else if (name == " ibset" ) {
362
361
fptr = &Scalar<T>::IBSET;
363
- } else if (name == " ishft" ) {
364
- fptr = &Scalar<T>::ISHFT;
365
- } else if (name == " shifta" ) {
366
- fptr = &Scalar<T>::SHIFTA;
367
- } else if (name == " shiftr" ) {
368
- fptr = &Scalar<T>::SHIFTR;
369
- } else if (name == " shiftl" ) {
370
- fptr = &Scalar<T>::SHIFTL;
371
362
} else {
372
363
common::die (" missing case to fold intrinsic function %s" , name.c_str ());
373
364
}
374
365
return FoldElementalIntrinsic<T, T, Int4>(context, std::move (funcRef),
375
- ScalarFunc<T, T, Int4>(
376
- [&fptr](const Scalar<T> &i, const Scalar<Int4> &pos) -> Scalar<T> {
377
- return std::invoke (fptr, i, static_cast <int >(pos.ToInt64 ()));
378
- }));
366
+ ScalarFunc<T, T, Int4>([&](const Scalar<T> &i,
367
+ const Scalar<Int4> &pos) -> Scalar<T> {
368
+ auto posVal{static_cast <int >(pos.ToInt64 ())};
369
+ if (posVal < 0 ) {
370
+ context.messages ().Say (
371
+ " bit position for %s (%d) is negative" _err_en_US, name, posVal);
372
+ } else if (posVal >= i.bits ) {
373
+ context.messages ().Say (
374
+ " bit position for %s (%d) is not less than %d" _err_en_US, name,
375
+ posVal, i.bits );
376
+ }
377
+ return std::invoke (fptr, i, posVal);
378
+ }));
379
379
} else if (name == " index" || name == " scan" || name == " verify" ) {
380
380
if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0 ])}) {
381
381
return std::visit (
@@ -437,6 +437,35 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
437
437
} else if (name == " iparity" ) {
438
438
return FoldBitReduction (
439
439
context, std::move (funcRef), &Scalar<T>::IEOR, Scalar<T>{});
440
+ } else if (name == " ishft" || name == " shifta" || name == " shiftr" ||
441
+ name == " shiftl" ) {
442
+ // Second argument can be of any kind. However, it must be smaller or
443
+ // equal than BIT_SIZE. It can be converted to Int4 to simplify.
444
+ auto fptr{&Scalar<T>::ISHFT};
445
+ if (name == " ishft" ) { // done in fptr definition
446
+ } else if (name == " shifta" ) {
447
+ fptr = &Scalar<T>::SHIFTA;
448
+ } else if (name == " shiftr" ) {
449
+ fptr = &Scalar<T>::SHIFTR;
450
+ } else if (name == " shiftl" ) {
451
+ fptr = &Scalar<T>::SHIFTL;
452
+ } else {
453
+ common::die (" missing case to fold intrinsic function %s" , name.c_str ());
454
+ }
455
+ return FoldElementalIntrinsic<T, T, Int4>(context, std::move (funcRef),
456
+ ScalarFunc<T, T, Int4>([&](const Scalar<T> &i,
457
+ const Scalar<Int4> &pos) -> Scalar<T> {
458
+ auto posVal{static_cast <int >(pos.ToInt64 ())};
459
+ if (posVal < 0 ) {
460
+ context.messages ().Say (
461
+ " shift count for %s (%d) is negative" _err_en_US, name, posVal);
462
+ } else if (posVal > i.bits ) {
463
+ context.messages ().Say (
464
+ " shift count for %s (%d) is greater than %d" _err_en_US, name,
465
+ posVal, i.bits );
466
+ }
467
+ return std::invoke (fptr, i, posVal);
468
+ }));
440
469
} else if (name == " lbound" ) {
441
470
return LBOUND (context, std::move (funcRef));
442
471
} else if (name == " leadz" || name == " trailz" || name == " poppar" ||
0 commit comments