Skip to content

Commit c6ec6e3

Browse files
committed
[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
1 parent 69bc8c9 commit c6ec6e3

File tree

3 files changed

+25
-12
lines changed

3 files changed

+25
-12
lines changed

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ class FoldingContext;
5656
// that can also be typeless values are encoded with an "elementalOrBOZ"
5757
// rank pattern.
5858
// Assumed-type (TYPE(*)) dummy arguments can be forwarded along to some
59-
// intrinsic functions that accept AnyType + Rank::anyOrAssumedRank or
60-
// AnyType + Kind::addressable.
59+
// intrinsic functions that accept AnyType + Rank::anyOrAssumedRank,
60+
// AnyType + Rank::arrayOrAssumedRank, or AnyType + Kind::addressable.
6161
using CategorySet = common::EnumSet<TypeCategory, 8>;
6262
static constexpr CategorySet IntType{TypeCategory::Integer};
6363
static constexpr CategorySet RealType{TypeCategory::Real};
@@ -203,7 +203,8 @@ ENUM_CLASS(Rank,
203203
coarray, // rank is known and can be scalar; has nonzero corank
204204
atom, // is scalar and has nonzero corank or is coindexed
205205
known, // rank is known and can be scalar
206-
anyOrAssumedRank, // rank can be unknown; assumed-type TYPE(*) allowed
206+
anyOrAssumedRank, // any rank, or assumed; assumed-type TYPE(*) allowed
207+
arrayOrAssumedRank, // rank >= 1 or assumed; assumed-type TYPE(*) allowed
207208
conformable, // scalar, or array of same rank & shape as "array" argument
208209
reduceOperation, // a pure function with constraints for REDUCE
209210
dimReduced, // scalar if no DIM= argument, else rank(array)-1
@@ -554,7 +555,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
554555
{{"array", AnyData, Rank::anyOrAssumedRank}, RequiredDIM,
555556
SizeDefaultKIND},
556557
KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction},
557-
{"lbound", {{"array", AnyData, Rank::anyOrAssumedRank}, SizeDefaultKIND},
558+
{"lbound", {{"array", AnyData, Rank::arrayOrAssumedRank}, SizeDefaultKIND},
558559
KINDInt, Rank::vector, IntrinsicClass::inquiryFunction},
559560
{"lcobound",
560561
{{"coarray", AnyData, Rank::coarray}, OptionalDIM, SizeDefaultKIND},
@@ -802,7 +803,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
802803
{"sind", {{"x", SameFloating}}, SameFloating},
803804
{"sinh", {{"x", SameFloating}}, SameFloating},
804805
{"size",
805-
{{"array", AnyData, Rank::anyOrAssumedRank},
806+
{{"array", AnyData, Rank::arrayOrAssumedRank},
806807
OptionalDIM, // unless array is assumed-size
807808
SizeDefaultKIND},
808809
KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction},
@@ -862,7 +863,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
862863
{{"array", AnyData, Rank::anyOrAssumedRank}, RequiredDIM,
863864
SizeDefaultKIND},
864865
KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction},
865-
{"ubound", {{"array", AnyData, Rank::anyOrAssumedRank}, SizeDefaultKIND},
866+
{"ubound", {{"array", AnyData, Rank::arrayOrAssumedRank}, SizeDefaultKIND},
866867
KINDInt, Rank::vector, IntrinsicClass::inquiryFunction},
867868
{"ucobound",
868869
{{"coarray", AnyData, Rank::coarray}, OptionalDIM, SizeDefaultKIND},
@@ -1689,7 +1690,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
16891690
if (arg->GetAssumedTypeDummy()) {
16901691
// TYPE(*) assumed-type dummy argument forwarded to intrinsic
16911692
if (d.typePattern.categorySet == AnyType &&
1692-
d.rank == Rank::anyOrAssumedRank &&
1693+
(d.rank == Rank::anyOrAssumedRank ||
1694+
d.rank == Rank::arrayOrAssumedRank) &&
16931695
(d.typePattern.kindCode == KindCode::any ||
16941696
d.typePattern.kindCode == KindCode::addressable)) {
16951697
continue;
@@ -1871,7 +1873,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
18711873
const IntrinsicDummyArgument &d{dummy[std::min(j, dummyArgPatterns - 1)]};
18721874
if (const ActualArgument *arg{actualForDummy[j]}) {
18731875
bool isAssumedRank{IsAssumedRank(*arg)};
1874-
if (isAssumedRank && d.rank != Rank::anyOrAssumedRank) {
1876+
if (isAssumedRank && d.rank != Rank::anyOrAssumedRank &&
1877+
d.rank != Rank::arrayOrAssumedRank) {
18751878
messages.Say(arg->sourceLocation(),
18761879
"Assumed-rank array cannot be forwarded to '%s=' argument"_err_en_US,
18771880
d.keyword);
@@ -1949,6 +1952,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
19491952
argOk = rank == knownArg->Rank();
19501953
break;
19511954
case Rank::anyOrAssumedRank:
1955+
case Rank::arrayOrAssumedRank:
1956+
if (d.rank == Rank::arrayOrAssumedRank && rank == 0) {
1957+
argOk = false;
1958+
break;
1959+
}
19521960
if (!dimArg && rank > 0 && !isAssumedRank &&
19531961
(std::strcmp(name, "shape") == 0 ||
19541962
std::strcmp(name, "size") == 0 ||
@@ -2245,6 +2253,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
22452253
case Rank::atom:
22462254
case Rank::known:
22472255
case Rank::anyOrAssumedRank:
2256+
case Rank::arrayOrAssumedRank:
22482257
case Rank::reduceOperation:
22492258
case Rank::dimRemovedOrScalar:
22502259
common::die("INTERNAL: bad Rank code on intrinsic '%s' result", name);

flang/test/Semantics/misc-intrinsics.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
22
! Miscellaneous constraint and requirement checking on intrinsics
33
program test_size
4+
real :: scalar
45
real, dimension(5, 5) :: array
56
call test(array)
67
contains
@@ -12,6 +13,12 @@ subroutine test(arg)
1213
print *, ubound(arg)
1314
!ERROR: The 'source=' argument to the intrinsic function 'shape' may not be assumed-size
1415
print *, shape(arg)
16+
!ERROR: missing mandatory 'dim=' argument
17+
print *, lbound(scalar)
18+
!ERROR: 'array=' argument has unacceptable rank 0
19+
print *, size(scalar)
20+
!ERROR: missing mandatory 'dim=' argument
21+
print *, ubound(scalar)
1522
! But these cases are fine:
1623
print *, size(arg, dim=1)
1724
print *, ubound(arg, dim=1)
@@ -21,6 +28,7 @@ subroutine test(arg)
2128
print *, lbound(array)
2229
print *, size(arg(:,1))
2330
print *, ubound(arg(:,1))
31+
print *, shape(scalar)
2432
print *, shape(arg(:,1))
2533
end subroutine
2634
end

flang/test/Semantics/symbol14.f90

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
!DEF: /MainProgram1/t2/b ObjectEntity REAL(4)
1616
!REF: /MainProgram1/t1/k
1717
real :: b(k)
18-
!DEF: /MainProgram1/t2/c ObjectEntity REAL(4)
19-
!DEF: /MainProgram1/size INTRINSIC, PURE (Function) ProcEntity
20-
!DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
21-
real :: c(size(a))
2218
!REF: /MainProgram1/t1
2319
!DEF: /MainProgram1/t2/x ObjectEntity TYPE(t1(k=666_4))
2420
type(t1) :: x

0 commit comments

Comments
 (0)