Skip to content

Commit 0775131

Browse files
committed
[flang] Fix crash in folding (#48437)
Elemental intrinsic function folding was not taking the lower bounds of constant array arguments into account; these lower bounds can be distinct from 1 when named constants appear as arguments. LLVM bugzilla #48437. Differential Revision: https://reviews.llvm.org/D93321
1 parent e2e86f4 commit 0775131

File tree

3 files changed

+25
-24
lines changed

3 files changed

+25
-24
lines changed

flang/include/flang/Evaluate/constant.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ template <typename T> class Constant : public ConstantBase<T> {
140140
}
141141
}
142142

143-
// Apply subscripts.
143+
// Apply subscripts. An empty subscript list is allowed for
144+
// a scalar constant.
144145
Element At(const ConstantSubscripts &) const;
145146

146147
Constant Reshape(ConstantSubscripts &&) const;
@@ -177,7 +178,7 @@ class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
177178
}
178179
}
179180

180-
// Apply subscripts
181+
// Apply subscripts, if any.
181182
Scalar<Result> At(const ConstantSubscripts &) const;
182183

183184
Constant Reshape(ConstantSubscripts &&) const;

flang/lib/Evaluate/fold-implementation.h

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,8 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
443443
// Compute the shape of the result based on shapes of arguments
444444
ConstantSubscripts shape;
445445
int rank{0};
446-
const ConstantSubscripts *shapes[sizeof...(TA)]{
447-
&std::get<I>(*args)->shape()...};
448-
const int ranks[sizeof...(TA)]{std::get<I>(*args)->Rank()...};
446+
const ConstantSubscripts *shapes[]{&std::get<I>(*args)->shape()...};
447+
const int ranks[]{std::get<I>(*args)->Rank()...};
449448
for (unsigned int i{0}; i < sizeof...(TA); ++i) {
450449
if (ranks[i] > 0) {
451450
if (rank == 0) {
@@ -470,20 +469,19 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
470469
std::vector<Scalar<TR>> results;
471470
if (TotalElementCount(shape) > 0) {
472471
ConstantBounds bounds{shape};
473-
ConstantSubscripts index(rank, 1);
472+
ConstantSubscripts resultIndex(rank, 1);
473+
ConstantSubscripts argIndex[]{std::get<I>(*args)->lbounds()...};
474474
do {
475475
if constexpr (std::is_same_v<WrapperType<TR, TA...>,
476476
ScalarFuncWithContext<TR, TA...>>) {
477-
results.emplace_back(func(context,
478-
(ranks[I] ? std::get<I>(*args)->At(index)
479-
: std::get<I>(*args)->GetScalarValue().value())...));
477+
results.emplace_back(
478+
func(context, std::get<I>(*args)->At(argIndex[I])...));
480479
} else if constexpr (std::is_same_v<WrapperType<TR, TA...>,
481480
ScalarFunc<TR, TA...>>) {
482-
results.emplace_back(func(
483-
(ranks[I] ? std::get<I>(*args)->At(index)
484-
: std::get<I>(*args)->GetScalarValue().value())...));
481+
results.emplace_back(func(std::get<I>(*args)->At(argIndex[I])...));
485482
}
486-
} while (bounds.IncrementSubscripts(index));
483+
(std::get<I>(*args)->IncrementSubscripts(argIndex[I]), ...);
484+
} while (bounds.IncrementSubscripts(resultIndex));
487485
}
488486
// Build and return constant result
489487
if constexpr (TR::category == TypeCategory::Character) {
@@ -732,17 +730,11 @@ template <typename T> class ArrayConstructorFolder {
732730
Expr<T> folded{Fold(context_, common::Clone(expr.value()))};
733731
if (const auto *c{UnwrapConstantValue<T>(folded)}) {
734732
// Copy elements in Fortran array element order
735-
ConstantSubscripts shape{c->shape()};
736-
int rank{c->Rank()};
737-
ConstantSubscripts index(GetRank(shape), 1);
738-
for (std::size_t n{c->size()}; n-- > 0;) {
739-
elements_.emplace_back(c->At(index));
740-
for (int d{0}; d < rank; ++d) {
741-
if (++index[d] <= shape[d]) {
742-
break;
743-
}
744-
index[d] = 1;
745-
}
733+
if (c->size() > 0) {
734+
ConstantSubscripts index{c->lbounds()};
735+
do {
736+
elements_.emplace_back(c->At(index));
737+
} while (c->IncrementSubscripts(index));
746738
}
747739
return true;
748740
} else {

flang/test/Evaluate/folding16.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %S/test_folding.sh %s %t %f18
2+
! Ensure that lower bounds are accounted for in intrinsic folding;
3+
! this is a regression test for a bug in which they were not
4+
real, parameter :: a(-1:-1) = 1.
5+
real, parameter :: b(-1:-1) = log(a)
6+
logical, parameter :: test = lbound(a,1)==-1 .and. lbound(b,1)==-1 .and. &
7+
lbound(log(a),1)==1 .and. all(b==0)
8+
end

0 commit comments

Comments
 (0)