llvm / llvm/llvm-project

[flang] Wrong LBOUND for ASSOCIATE name when the selector is a pointer-valued function reference

Open
#220,736 2 comments 0 reactions 0 assignees View on GitHub
flang
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

When the selector of an ASSOCIATE construct is a reference to a function with a data pointer result, flang gives the associate-name a lower bound of 1 instead of the lower bound of the pointer's target. Subscript addressing, however, correctly uses the target's bounds, so `LBOUND` is inconsistent with the element addressing flang itself performs.

## Reproducer

```fortran
program assoc_contained
implicit none
real, target :: tgt(2:4) = [20., 30., 40.]

associate (fv => f_val(), fp => f_ptr())
print *, 'lbound(f_val()) =', lbound(fv)
print *, 'lbound(f_ptr()) =', lbound(fp)
fp(2) = -20. ! still a variable per R902/C902
end associate
print *, 'tgt after write via fp =', tgt

contains

function f_ptr() result(p)
real, pointer :: p(:)
p => tgt ! host-associated target
end function

function f_val() result(w)
real :: w(2:4)
w = [1., 2., 3.]
end function

end program
```

## Actual output (flang 22.1.8)

```
$ flang -pedantic fortran/assoc_contained.f90 && ./a.out
lbound(f_val()) = 1
lbound(f_ptr()) = 1
tgt after write via fp = -20. 30. 40.
```

Note the inconsistency in the actual output: the assignment `fp(2) = -20.` modifies `tgt(2)` — i.e. flang's addressing of `fp` uses lower bound 2 — yet `lbound(fp)` reports 1. It looks like semantics computes the associate-name's bounds as if the selector were a non-variable expression, while lowering carries the descriptor's true bounds.

According to [a comment by](https://github.com/klausler/fortran-wringer-tests/issues/18#issuecomment-5512037406) @klausler, the correct result would be if,

> ... flang printed 1, 2, and an array whose first element has been negated.

This would also match what I see with other compilers (gfortran, ifx, nagfor). Thanks to @rouson for doing the NAG test.

(This message was drafted with help of Claude.)

Contributor guide

Open the contributing guide

Research direction

Start by compiling and running the provided ASSOCIATE reproducer with flang, comparing LBOUND results with the pointer target's bounds and the observed assignment behavior. Trace flang's semantic handling of associate names for pointer-valued function references and its descriptor lowering. Done means LBOUND(fp) reports 2 while the write still updates tgt(2), without regressing the non-pointer f_val() case.

Written by the indexing model from the issue text.

Assessment

Tech stack
fortran
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.