Skip to content

Commit d8b588b

Browse files
klauslervdonaldson
authored andcommitted
[flang] Re-fold bounds expressions in DATA implied DO loops
To accommodate triangular implied DO loops in DATA statements, in which the bounds of nested implied DO loops might depend on the values of the indices of outer implied DO loops in the same DATA statement set, it is necessary to run them through constant folding each time they are encountered. Differential Revision: https://reviews.llvm.org/D114754
1 parent 48e5bc4 commit d8b588b

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

flang/lib/Semantics/data-to-inits.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,23 +155,32 @@ bool DataInitializationCompiler::Scan(const parser::DataImpliedDo &ido) {
155155
const auto *stepExpr{
156156
bounds.step ? GetExpr(bounds.step->thing.thing) : nullptr};
157157
if (lowerExpr && upperExpr) {
158-
auto lower{ToInt64(*lowerExpr)};
159-
auto upper{ToInt64(*upperExpr)};
160-
auto step{stepExpr ? ToInt64(*stepExpr) : std::nullopt};
161-
auto stepVal{step.value_or(1)};
162-
if (stepVal == 0) {
163-
exprAnalyzer_.Say(name.source,
164-
"DATA statement implied DO loop has a step value of zero"_err_en_US);
165-
} else if (lower && upper) {
158+
// Fold the bounds expressions (again) in case any of them depend
159+
// on outer implied DO loops.
160+
evaluate::FoldingContext &context{exprAnalyzer_.GetFoldingContext()};
161+
std::int64_t stepVal{1};
162+
if (stepExpr) {
163+
auto foldedStep{evaluate::Fold(context, SomeExpr{*stepExpr})};
164+
stepVal = ToInt64(foldedStep).value_or(1);
165+
if (stepVal == 0) {
166+
exprAnalyzer_.Say(name.source,
167+
"DATA statement implied DO loop has a step value of zero"_err_en_US);
168+
return false;
169+
}
170+
}
171+
auto foldedLower{evaluate::Fold(context, SomeExpr{*lowerExpr})};
172+
auto lower{ToInt64(foldedLower)};
173+
auto foldedUpper{evaluate::Fold(context, SomeExpr{*upperExpr})};
174+
auto upper{ToInt64(foldedUpper)};
175+
if (lower && upper) {
166176
int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
167177
if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
168178
if (dynamicType->category() == TypeCategory::Integer) {
169179
kind = dynamicType->kind();
170180
}
171181
}
172182
if (exprAnalyzer_.AddImpliedDo(name.source, kind)) {
173-
auto &value{exprAnalyzer_.GetFoldingContext().StartImpliedDo(
174-
name.source, *lower)};
183+
auto &value{context.StartImpliedDo(name.source, *lower)};
175184
bool result{true};
176185
for (auto n{(*upper - value + stepVal) / stepVal}; n > 0;
177186
--n, value += stepVal) {
@@ -183,7 +192,7 @@ bool DataInitializationCompiler::Scan(const parser::DataImpliedDo &ido) {
183192
}
184193
}
185194
}
186-
exprAnalyzer_.GetFoldingContext().EndImpliedDo(name.source);
195+
context.EndImpliedDo(name.source);
187196
exprAnalyzer_.RemoveImpliedDo(name.source);
188197
return result;
189198
}

0 commit comments

Comments
 (0)