@@ -323,10 +323,10 @@ class GetLowerBoundHelper
323
323
if (IsActuallyConstant (exprLowerBound)) {
324
324
return std::move (exprLowerBound);
325
325
} else {
326
- // If the lower bound of the associated entity is not resolved to
326
+ // If the lower bound of the associated entity is not resolved to a
327
327
// constant expression at the time of the association, it is unsafe
328
328
// to re-evaluate it later in the associate construct. Statements
329
- // in- between may have modified its operands value.
329
+ // in between may have modified its operands value.
330
330
return ExtentExpr{DescriptorInquiry{std::move (base),
331
331
DescriptorInquiry::Field::LowerBound, dimension_}};
332
332
}
@@ -476,24 +476,23 @@ static MaybeExtentExpr GetNonNegativeExtent(
476
476
}
477
477
}
478
478
479
- MaybeExtentExpr GetAssociatedExtent (const NamedEntity &base,
480
- const semantics::AssocEntityDetails &assoc, int dimension) {
481
- if (auto shape{GetShape (assoc.expr ())}) {
482
- if (dimension < static_cast <int >(shape->size ())) {
483
- auto &extent{shape->at (dimension)};
484
- if (extent && IsActuallyConstant (*extent)) {
479
+ static MaybeExtentExpr GetAssociatedExtent (
480
+ const Symbol &symbol, int dimension) {
481
+ if (const auto *assoc{symbol.detailsIf <semantics::AssocEntityDetails>()};
482
+ assoc && !assoc->rank ()) { // not SELECT RANK case
483
+ if (auto shape{GetShape (assoc->expr ())};
484
+ shape && dimension < static_cast <int >(shape->size ())) {
485
+ if (auto &extent{shape->at (dimension)};
486
+ // Don't return a non-constant extent, as the variables that
487
+ // determine the shape of the selector's expression may change
488
+ // during execution of the construct.
489
+ extent && IsActuallyConstant (*extent)) {
485
490
return std::move (extent);
486
- } else {
487
- // Otherwise, evaluating the associated expression extent expression
488
- // after the associate statement is unsafe given statements inside the
489
- // associate may have modified the associated expression operands
490
- // values.
491
- return ExtentExpr{DescriptorInquiry{
492
- NamedEntity{base}, DescriptorInquiry::Field::Extent, dimension}};
493
491
}
494
492
}
495
493
}
496
- return std::nullopt;
494
+ return ExtentExpr{DescriptorInquiry{
495
+ NamedEntity{symbol}, DescriptorInquiry::Field::Extent, dimension}};
497
496
}
498
497
499
498
MaybeExtentExpr GetExtent (
@@ -508,14 +507,16 @@ MaybeExtentExpr GetExtent(
508
507
if (semantics::IsDescriptor (symbol) && dimension < *assoc->rank ()) {
509
508
return ExtentExpr{DescriptorInquiry{
510
509
NamedEntity{base}, DescriptorInquiry::Field::Extent, dimension}};
510
+ } else {
511
+ return std::nullopt;
511
512
}
512
513
} else {
513
- return GetAssociatedExtent (base, *assoc , dimension);
514
+ return GetAssociatedExtent (last , dimension);
514
515
}
515
516
}
516
517
if (const auto *details{symbol.detailsIf <semantics::ObjectEntityDetails>()}) {
517
518
if (IsImpliedShape (symbol) && details->init ()) {
518
- if (auto shape{GetShape (symbol)}) {
519
+ if (auto shape{GetShape (symbol, invariantOnly )}) {
519
520
if (dimension < static_cast <int >(shape->size ())) {
520
521
return std::move (shape->at (dimension));
521
522
}
@@ -527,7 +528,7 @@ MaybeExtentExpr GetExtent(
527
528
if (auto extent{GetNonNegativeExtent (shapeSpec, invariantOnly)}) {
528
529
return extent;
529
530
} else if (details->IsAssumedSize () && j == symbol.Rank ()) {
530
- return std::nullopt ;
531
+ break ;
531
532
} else if (semantics::IsDescriptor (symbol)) {
532
533
return ExtentExpr{DescriptorInquiry{NamedEntity{base},
533
534
DescriptorInquiry::Field::Extent, dimension}};
@@ -620,7 +621,7 @@ MaybeExtentExpr GetRawUpperBound(
620
621
return std::nullopt;
621
622
} else if (assoc->rank () && dimension >= *assoc->rank ()) {
622
623
return std::nullopt;
623
- } else if (auto extent{GetAssociatedExtent (base, *assoc , dimension)}) {
624
+ } else if (auto extent{GetAssociatedExtent (symbol , dimension)}) {
624
625
return ComputeUpperBound (
625
626
GetRawLowerBound (base, dimension), std::move (extent));
626
627
}
@@ -680,11 +681,9 @@ static MaybeExtentExpr GetUBOUND(FoldingContext *context,
680
681
std::move (base), DescriptorInquiry::Field::Extent, dimension}};
681
682
return ComputeUpperBound (std::move (lb), std::move (extent));
682
683
}
683
- } else if (assoc->expr ()) {
684
- if (auto extent{GetAssociatedExtent (base, *assoc, dimension)}) {
685
- if (auto lb{GetLBOUND (base, dimension, invariantOnly)}) {
686
- return ComputeUpperBound (std::move (*lb), std::move (extent));
687
- }
684
+ } else if (auto extent{GetAssociatedExtent (symbol, dimension)}) {
685
+ if (auto lb{GetLBOUND (base, dimension, invariantOnly)}) {
686
+ return ComputeUpperBound (std::move (*lb), std::move (extent));
688
687
}
689
688
}
690
689
}
@@ -768,7 +767,7 @@ auto GetShapeHelper::operator()(const Symbol &symbol) const -> Result {
768
767
auto resultShape{(*this )(subp.result ())};
769
768
if (resultShape && !useResultSymbolShape_) {
770
769
// Ensure the shape is constant. Otherwise, it may be referring
771
- // to symbols that belong to the subroutine scope and are
770
+ // to symbols that belong to the function's scope and are
772
771
// meaningless on the caller side without the related call
773
772
// expression.
774
773
for (auto &extent : *resultShape) {
@@ -799,9 +798,6 @@ auto GetShapeHelper::operator()(const Component &component) const -> Result {
799
798
} else if (symbol.has <semantics::ObjectEntityDetails>()) {
800
799
NamedEntity base{Component{component}};
801
800
return CreateShape (rank, base);
802
- } else if (symbol.has <semantics::AssocEntityDetails>()) {
803
- NamedEntity base{Component{component}};
804
- return Result{CreateShape (rank, base)};
805
801
} else {
806
802
return (*this )(symbol);
807
803
}
@@ -878,6 +874,7 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
878
874
}
879
875
return ScalarShape ();
880
876
} else if (const Symbol * symbol{call.proc ().GetSymbol ()}) {
877
+ auto restorer{common::ScopedSet (useResultSymbolShape_, false )};
881
878
return (*this )(*symbol);
882
879
} else if (const auto *intrinsic{call.proc ().GetSpecificIntrinsic ()}) {
883
880
if (intrinsic->name == " shape" || intrinsic->name == " lbound" ||
0 commit comments