[flang-commits] [flang] [flang][Lower] Implement lowering for new expression kind used in explicit-shape-bounds-spec (PR #215403)

via flang-commits flang-commits at lists.llvm.org
Wed Oct 14 01:13:08 PDT 2026


================
@@ -895,11 +895,21 @@ llvm::raw_ostream &DescriptorInquiry::AsFortran(llvm::raw_ostream &o) const {
 }
 
 llvm::raw_ostream &RankOneBoundElement::AsFortran(llvm::raw_ostream &o) const {
-  // A RankOneBoundElement extracts a single element from a rank-1 array that
-  // was used as an array bound in a declaration; it has no true Fortran
-  // surface syntax.  Render it in an internal, clearly-synthetic form.
-  base().AsFortran(o << "rank1BoundElement(")
-      << ",dim=" << (dimension_ + 1) << ')';
+  if (originatingArray_) {
+    // This element was produced by folding an UBOUND()/LBOUND() inquiry of an
+    // explicit-shape array declared with a rank-1 array bound.  Serialize it as
+    // the originating intrinsic so the mod file round-trips as real Fortran.
+    o << (isUpperBound_ ? "ubound(" : "lbound(");
+    originatingArray_->AsFortran(o);
----------------
MattPD wrote:

The originating array is not part of the expression traversed by `CollectSymbols`, since `Traverse` visits only `base()`. The module file can therefore omit the array or declare it too late. When a host entity has the same name, a separately compiled caller silently gets a wrong result size.

You can reproduce this by saving the following as `provider.f90`:

```fortran
module dependency_shadow_provider
  implicit none
  real :: local_shape(2, 9)
contains
  function make_result(n, m, mask) result(r)
    integer, intent(in) :: n(2), m(2)
    logical, intent(in) :: mask(2)
    real :: local_shape(merge(n, m, mask))
    real :: r(ubound(local_shape, 2))
    r = 7.0
  end function
end module
```

Save the following as `consumer.f90`:

```fortran
program dependency_shadow_consumer
  use dependency_shadow_provider, only : make_result
  implicit none
  real, allocatable :: x(:)
  x = make_result([2, 3], [4, 5], [.true., .true.])
  print '(i0)', size(x)
end program
```

Then run `flang -c provider.f90 && flang consumer.f90 provider.o && ./a.out`. The command prints `9` instead of the expected `3`. At the previous PR head 14764c2f, the same command prints `3`.

The module file declares `r` using `ubound(local_shape,dim=2,kind=8)` but omits the function's own `local_shape`.

Without the module-level array, the consumer instead fails with `'array=' argument has unacceptable rank 0`. The same rejection occurs when the originating array is a dummy following the dependent array in the argument list: `subroutine s(n,m,c,b,z)` with `real :: z(merge(n,m,c))` and `real :: b(size(z,2))`.

https://github.com/llvm/llvm-project/pull/215403


More information about the flang-commits mailing list