@@ -189,7 +189,9 @@ ENUM_CLASS(Rank,
189
189
shaped, // rank is length of SHAPE vector
190
190
)
191
191
192
- ENUM_CLASS (Optionality, required, optional, missing,
192
+ ENUM_CLASS (Optionality, required,
193
+ optional, // unless DIM= for SIZE(assumedSize)
194
+ missing, // for DIM= cases like FINDLOC
193
195
defaultsToSameKind, // for MatchingDefaultKIND
194
196
defaultsToDefaultForResult, // for DefaultingKIND
195
197
defaultsToSizeKind, // for SizeDefaultKIND
@@ -722,7 +724,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
722
724
{" sind" , {{" x" , SameFloating}}, SameFloating},
723
725
{" sinh" , {{" x" , SameFloating}}, SameFloating},
724
726
{" size" ,
725
- {{" array" , AnyData, Rank::anyOrAssumedRank}, OptionalDIM,
727
+ {{" array" , AnyData, Rank::anyOrAssumedRank},
728
+ OptionalDIM, // unless array is assumed-size
726
729
SizeDefaultKIND},
727
730
KINDInt, Rank::scalar, IntrinsicClass::inquiryFunction},
728
731
{" sizeof" , {{" a" , AnyData, Rank::anyOrAssumedRank}}, SubscriptInt,
@@ -1372,7 +1375,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1372
1375
for (std::size_t j{0 }; j < dummies; ++j) {
1373
1376
const IntrinsicDummyArgument &d{dummy[std::min (j, dummyArgPatterns - 1 )]};
1374
1377
if (const ActualArgument * arg{actualForDummy[j]}) {
1375
- if (IsAssumedRank (*arg) && d.rank != Rank::anyOrAssumedRank) {
1378
+ bool isAssumedRank{IsAssumedRank (*arg)};
1379
+ if (isAssumedRank && d.rank != Rank::anyOrAssumedRank) {
1376
1380
messages.Say (" Assumed-rank array cannot be forwarded to "
1377
1381
" '%s=' argument" _err_en_US,
1378
1382
d.keyword );
@@ -1443,14 +1447,39 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1443
1447
argOk = rank == knownArg->Rank ();
1444
1448
break ;
1445
1449
case Rank::anyOrAssumedRank:
1450
+ if (!hasDimArg && rank > 0 && !isAssumedRank &&
1451
+ (std::strcmp (name, " shape" ) == 0 ||
1452
+ std::strcmp (name, " size" ) == 0 ||
1453
+ std::strcmp (name, " ubound" ) == 0 )) {
1454
+ // Check for an assumed-size array argument.
1455
+ // These are disallowed for SHAPE, and require DIM= for
1456
+ // SIZE and UBOUND.
1457
+ // (A previous error message for UBOUND will take precedence
1458
+ // over this one, as this error is caught by the second entry
1459
+ // for UBOUND.)
1460
+ if (std::optional<Shape> shape{GetShape (context, *arg)}) {
1461
+ if (!shape->empty () && !shape->back ().has_value ()) {
1462
+ if (strcmp (name, " shape" ) == 0 ) {
1463
+ messages.Say (
1464
+ " The '%s=' argument to the intrinsic function '%s' may not be assumed-size" _err_en_US,
1465
+ d.keyword , name);
1466
+ } else {
1467
+ messages.Say (
1468
+ " A dim= argument is required for '%s' when the array is assumed-size" _err_en_US,
1469
+ name);
1470
+ }
1471
+ return std::nullopt;
1472
+ }
1473
+ }
1474
+ }
1446
1475
argOk = true ;
1447
1476
break ;
1448
1477
case Rank::conformable: // arg must be conformable with previous arrayArg
1449
1478
CHECK (arrayArg);
1450
1479
CHECK (arrayArgName);
1451
1480
if (const std::optional<Shape> &arrayArgShape{
1452
1481
GetShape (context, *arrayArg)}) {
1453
- if (const std::optional<Shape> & argShape{GetShape (context, *arg)}) {
1482
+ if (std::optional<Shape> argShape{GetShape (context, *arg)}) {
1454
1483
std::string arrayArgMsg{" '" };
1455
1484
arrayArgMsg = arrayArgMsg + arrayArgName + " ='" + " argument" ;
1456
1485
std::string argMsg{" '" };
0 commit comments