[flang-commits] [flang] [flang] Fix LBOUND of associate name with pointer function selector (PR #224753)
via flang-commits
flang-commits at lists.llvm.org
Fri Sep 18 14:52:05 PDT 2026
https://github.com/linisha15 created https://github.com/llvm/llvm-project/pull/224753
Fixes #220736.
# Problem
When the selector of an ASSOCIATE construct is a reference to a function
that returns a pointer array, `lbound` of the associate name returned 1
instead of the lower bound of the pointer's target:
associate (fp => f_ptr()) ! f_ptr() returns a pointer to tgt(2:4)
print *, lbound(fp) ! printed 1, should be 2
fp(2) = -20. ! correctly modifies tgt(2)
end associate
A reference to a pointer-valued function is a variable, so the associate
name takes the target's bounds. Subscripting already did this; `LBOUND`
did not.
# Cause
`GetLowerBoundHelper` in `Evaluate/shape.cpp` returns a constant lower
bound of 1 for any expression that is not a whole symbol or a constant.
That treated a pointer-valued function reference like an ordinary
operation, so `LBOUND` was folded to 1 at compile time.
# Fix
Skip that default when the expression is a reference to a pointer-valued
function. The existing code for associate names then uses a descriptor
inquiry, so the bound is read at run time from the descriptor, as
lowering already does for subscripts. Array sections, components and
non-pointer function results still fold to 1.
# Test
Adds `Semantics/associate05.f90`: `lbound(fp, 1)` on such an associate
name must not be accepted as a constant expression. Without this change
no error is reported; with it, "Must be a constant value" is reported.
A non-pointer function result is not affected.
# How I checked it
- Ran flang's parser and semantic analysis on the issue's reproducer,
with and without the change. Only the pointer-function case differs.
- Compared diagnostics, symbol tables and folded expressions with and
without the change across the 2,980 `.f90`/`.F90` files under
`flang/test/{Semantics,Evaluate,Lower}`. The only difference is the new
test. (31 files could not be analyzed by my standalone runner because
the built-in module files were missing.)
- clang-format is clean on the changed lines.
### Not checked locally
My machine could not build the full compiler, so I have not run
`check-flang`/`lit`, the reproducer end to end, or any lowering tests.
>From reading the code, lowering already takes bounds from the descriptor,
so `lbound(fp)` should now print 2. I am relying on CI to confirm.
>From b651c3ea00f407011c196b069f501cfdeca61983 Mon Sep 17 00:00:00 2001
From: linisha <linisha232 at gmail.com>
Date: Sat, 19 Sep 2026 03:16:06 +0530
Subject: [PATCH] [flang] Don't fold LBOUND of ASSOCIATE name with pointer
function selector
---
flang/lib/Evaluate/shape.cpp | 4 +++-
flang/test/Semantics/associate05.f90 | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Semantics/associate05.f90
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index 27913c3559c71..e2e85937c97d9 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -368,7 +368,9 @@ class GetLowerBoundHelper
if (dimension_ < GetRank(lb)) {
return Result{lb[dimension_]};
}
- } else { // operation
+ } else if (!(UnwrapProcedureRef(expr) && IsVariable(expr))) {
+ // operation (a reference to a POINTER-valued function is a variable
+ // whose lower bounds come from its result's descriptor)
return Result{1};
}
} else {
diff --git a/flang/test/Semantics/associate05.f90 b/flang/test/Semantics/associate05.f90
new file mode 100644
index 0000000000000..951d1fb345446
--- /dev/null
+++ b/flang/test/Semantics/associate05.f90
@@ -0,0 +1,27 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! The lower bounds of an associate name whose selector is a reference to a
+! function with a POINTER result are those of the pointer's target, which are
+! not known at compile time. LBOUND() of such a name must therefore not be
+! folded to a constant. A non-pointer function result still has default
+! lower bounds.
+module m
+ real, target :: tgt(2:4)
+ contains
+ function f_ptr()
+ real, pointer :: f_ptr(:)
+ f_ptr => tgt
+ end function
+ function f_val()
+ real :: f_val(2:4)
+ f_val = 0.
+ end function
+ subroutine test
+ associate (fp => f_ptr(), fv => f_val())
+ block
+ !ERROR: Must be a constant value
+ integer, parameter :: k1 = lbound(fp, 1)
+ integer, parameter :: k2 = lbound(fv, 1)
+ end block
+ end associate
+ end subroutine
+end module
More information about the flang-commits
mailing list