Skip to content

Commit

Permalink
[flang][runtime] Fix empty FINDLOC() results (#75251)
Browse files Browse the repository at this point in the history
When FINDLOC() can't find its target value among the unmasked array
elements, it must return a zero result. Its implementation doesn't
sufficiently distinguish a zero result from a hit in an array with lower
bound(s) less than one. Fix by adding a flag to distinguish the case
with no hits from cases with hits.

Fixes llvm-test-suite/Fortran/gfortran/regression/findloc_6.f90.
  • Loading branch information
klausler committed Dec 26, 2023
1 parent 8fc045e commit 475d18f
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions flang/runtime/findloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,27 @@ template <typename EQUALITY> class LocationAccumulator {
public:
LocationAccumulator(
const Descriptor &array, const Descriptor &target, bool back)
: array_{array}, target_{target}, back_{back} {
Reinitialize();
}
void Reinitialize() {
// per standard: result indices are all zero if no data
for (int j{0}; j < rank_; ++j) {
location_[j] = 0;
}
}
: array_{array}, target_{target}, back_{back} {}
void Reinitialize() { gotAnything_ = false; }
template <typename A> void GetResult(A *p, int zeroBasedDim = -1) {
if (zeroBasedDim >= 0) {
*p = location_[zeroBasedDim] -
array_.GetDimension(zeroBasedDim).LowerBound() + 1;
} else {
*p = gotAnything_ ? location_[zeroBasedDim] -
array_.GetDimension(zeroBasedDim).LowerBound() + 1
: 0;
} else if (gotAnything_) {
for (int j{0}; j < rank_; ++j) {
p[j] = location_[j] - array_.GetDimension(j).LowerBound() + 1;
}
} else {
// no unmasked hits? result is all zeroes
for (int j{0}; j < rank_; ++j) {
p[j] = 0;
}
}
}
template <typename IGNORED> bool AccumulateAt(const SubscriptValue at[]) {
if (equality_(array_, at, target_)) {
gotAnything_ = true;
for (int j{0}; j < rank_; ++j) {
location_[j] = at[j];
}
Expand All @@ -119,6 +119,7 @@ template <typename EQUALITY> class LocationAccumulator {
const Descriptor &target_;
const bool back_{false};
const int rank_{array_.rank()};
bool gotAnything_{false};
SubscriptValue location_[maxRank];
const EQUALITY equality_{};
};
Expand Down

0 comments on commit 475d18f

Please sign in to comment.