[flang][Evaluate] Add IntrinsicCall::impureFunction to RAND and IRAND (#170492)

This PR adds the` impureFunction` intrinsicClass for intrinsics wich are
function such as RAND and IRAND, which are not PURE functions in the GNU
extension and therefore cannot be called in a DO CONCURRENT (see
`test-suite::gfortran-regression-compile-regression__pr119836_2_f90.test`
). The `Pure` attribute will not be added for these intrinsics.
This commit is contained in:
Jean-Didier PAILLEUX
2025-12-04 07:57:18 +01:00
committed by GitHub
parent 4fcb6e11c1
commit c8a7a3a70d
3 changed files with 16 additions and 4 deletions

View File

@@ -63,7 +63,7 @@ struct SpecificIntrinsicFunctionInterface : public characteristics::Procedure {
// Generic intrinsic classes from table 16.1
ENUM_CLASS(IntrinsicClass, atomicSubroutine, collectiveSubroutine,
elementalFunction, elementalSubroutine, inquiryFunction, pureSubroutine,
impureSubroutine, transformationalFunction, noClass)
impureFunction, impureSubroutine, transformationalFunction, noClass)
class IntrinsicProcTable {
private:

View File

@@ -657,7 +657,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"irand",
{{"i", TypePattern{IntType, KindCode::exactKind, 4}, Rank::scalar,
Optionality::optional}},
TypePattern{IntType, KindCode::exactKind, 4}, Rank::scalar},
TypePattern{IntType, KindCode::exactKind, 4}, Rank::scalar,
IntrinsicClass::impureFunction},
{"ishft", {{"i", SameIntOrUnsigned}, {"shift", AnyInt}}, SameIntOrUnsigned},
{"ishftc",
{{"i", SameIntOrUnsigned}, {"shift", AnyInt},
@@ -879,7 +880,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"rand",
{{"i", TypePattern{IntType, KindCode::exactKind, 4}, Rank::scalar,
Optionality::optional}},
TypePattern{RealType, KindCode::exactKind, 4}, Rank::scalar},
TypePattern{RealType, KindCode::exactKind, 4}, Rank::scalar,
IntrinsicClass::impureFunction},
{"range",
{{"x", AnyNumeric, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::In,
@@ -2834,7 +2836,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
name, characteristics::Procedure{std::move(dummyArgs), attrs}},
std::move(rearranged)};
} else {
attrs.set(characteristics::Procedure::Attr::Pure);
if (intrinsicClass != IntrinsicClass::impureFunction /* RAND and IRAND */)
attrs.set(characteristics::Procedure::Attr::Pure);
characteristics::TypeAndShape typeAndShape{resultType.value(), resultRank};
characteristics::FunctionResult funcResult{std::move(typeAndShape)};
characteristics::Procedure chars{

View File

@@ -211,6 +211,7 @@ subroutine s7()
type(procTypeNotPure) :: procVarNotPure
type(procTypePure) :: procVarPure
integer :: ivar
real :: rvar
procVarPure%pureProcComponent => pureFunc
@@ -239,6 +240,14 @@ subroutine s7()
ivar = generic()
end do
! This should generate an error
do concurrent (i = 1:10)
!ERROR: Impure procedure 'irand' may not be referenced in DO CONCURRENT
ivar = irand()
!ERROR: Impure procedure 'rand' may not be referenced in DO CONCURRENT
rvar = rand()
end do
contains
integer function notPureFunc()
notPureFunc = 2