diff options
author | Peter Klausler <pklausler@nvidia.com> | 2023-03-20 11:44:56 -0700 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2023-03-28 04:39:44 -0700 |
commit | c6ec6e30867d07d5f641cdc34463a9588bdb9d22 (patch) | |
tree | 5acc97238d99175305cf1379e61578f6136effb3 /flang/lib/Evaluate/intrinsics.cpp | |
parent | 69bc8c9e2ad94fa367701b8ecadb39d693c41a3e (diff) | |
download | llvm-c6ec6e30867d07d5f641cdc34463a9588bdb9d22.zip llvm-c6ec6e30867d07d5f641cdc34463a9588bdb9d22.tar.gz llvm-c6ec6e30867d07d5f641cdc34463a9588bdb9d22.tar.bz2 |
[flang] Disallow scalar argument to SIZE/LBOUND/UBOUND
The compiler accepts arguments of any rank, or assumed rank, to a host
of intrinsic inquiry functions. For scalars, this is correct for most
of them, but the standard (and other compilers) prohibit scalar arguments
to SIZE, LBOUND, and UBOUND (without DIM=).
There are meaningful interpretations for these intrinsic inquiries
on scalars, but since there's no portability concern here, continuing
to support them would be an unjustifiable extension.
Differential Revision: https://reviews.llvm.org/D146587
Diffstat (limited to 'flang/lib/Evaluate/intrinsics.cpp')
-rw-r--r-- | flang/lib/Evaluate/intrinsics.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index a27d211..e82b62e 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -56,8 +56,8 @@ class FoldingContext; // that can also be typeless values are encoded with an "elementalOrBOZ" // rank pattern. // Assumed-type (TYPE(*)) dummy arguments can be forwarded along to some -// intrinsic functions that accept AnyType + Rank::anyOrAssumedRank or -// AnyType + Kind::addressable. +// intrinsic functions that accept AnyType + Rank::anyOrAssumedRank, +// AnyType + Rank::arrayOrAssumedRank, or AnyType + Kind::addressable. using CategorySet = common::EnumSet<TypeCategory, 8>; static constexpr CategorySet IntType{TypeCategory::Integer}; static constexpr CategorySet RealType{TypeCategory::Real}; @@ -203,7 +203,8 @@ ENUM_CLASS(Rank, coarray, // rank is known and can be scalar; has nonzero corank atom, // is scalar and has nonzero corank or is coindexed known, // rank is known and can be scalar - anyOrAssumedRank, // rank can be unknown; assumed-type TYPE(*) allowed + anyOrAssumedRank, // any rank, or assumed; assumed-type TYPE(*) allowed + arrayOrAssumedRank, // rank >= 1 or assumed; assumed-type TYPE(*) allowed conformable, // scalar, or array of same rank & shape as "array" argument reduceOperation, // a pure function with constraints for REDUCE dimReduced, // scalar if no DIM= argument, else rank(array)-1 @@ -554,7 +555,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {{"array", AnyData, Rank::anyOrAssumedRank}, RequiredDIM, SizeDefaultKIND}, KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction}, - {"lbound", {{"array", AnyData, Rank::anyOrAssumedRank}, SizeDefaultKIND}, + {"lbound", {{"array", AnyData, Rank::arrayOrAssumedRank}, SizeDefaultKIND}, KINDInt, Rank::vector, IntrinsicClass::inquiryFunction}, {"lcobound", {{"coarray", AnyData, Rank::coarray}, OptionalDIM, SizeDefaultKIND}, @@ -802,7 +803,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {"sind", {{"x", SameFloating}}, SameFloating}, {"sinh", {{"x", SameFloating}}, SameFloating}, {"size", - {{"array", AnyData, Rank::anyOrAssumedRank}, + {{"array", AnyData, Rank::arrayOrAssumedRank}, OptionalDIM, // unless array is assumed-size SizeDefaultKIND}, KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction}, @@ -862,7 +863,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {{"array", AnyData, Rank::anyOrAssumedRank}, RequiredDIM, SizeDefaultKIND}, KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction}, - {"ubound", {{"array", AnyData, Rank::anyOrAssumedRank}, SizeDefaultKIND}, + {"ubound", {{"array", AnyData, Rank::arrayOrAssumedRank}, SizeDefaultKIND}, KINDInt, Rank::vector, IntrinsicClass::inquiryFunction}, {"ucobound", {{"coarray", AnyData, Rank::coarray}, OptionalDIM, SizeDefaultKIND}, @@ -1689,7 +1690,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match( if (arg->GetAssumedTypeDummy()) { // TYPE(*) assumed-type dummy argument forwarded to intrinsic if (d.typePattern.categorySet == AnyType && - d.rank == Rank::anyOrAssumedRank && + (d.rank == Rank::anyOrAssumedRank || + d.rank == Rank::arrayOrAssumedRank) && (d.typePattern.kindCode == KindCode::any || d.typePattern.kindCode == KindCode::addressable)) { continue; @@ -1871,7 +1873,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match( const IntrinsicDummyArgument &d{dummy[std::min(j, dummyArgPatterns - 1)]}; if (const ActualArgument *arg{actualForDummy[j]}) { bool isAssumedRank{IsAssumedRank(*arg)}; - if (isAssumedRank && d.rank != Rank::anyOrAssumedRank) { + if (isAssumedRank && d.rank != Rank::anyOrAssumedRank && + d.rank != Rank::arrayOrAssumedRank) { messages.Say(arg->sourceLocation(), "Assumed-rank array cannot be forwarded to '%s=' argument"_err_en_US, d.keyword); @@ -1949,6 +1952,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match( argOk = rank == knownArg->Rank(); break; case Rank::anyOrAssumedRank: + case Rank::arrayOrAssumedRank: + if (d.rank == Rank::arrayOrAssumedRank && rank == 0) { + argOk = false; + break; + } if (!dimArg && rank > 0 && !isAssumedRank && (std::strcmp(name, "shape") == 0 || std::strcmp(name, "size") == 0 || @@ -2245,6 +2253,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match( case Rank::atom: case Rank::known: case Rank::anyOrAssumedRank: + case Rank::arrayOrAssumedRank: case Rank::reduceOperation: case Rank::dimRemovedOrScalar: common::die("INTERNAL: bad Rank code on intrinsic '%s' result", name); |