[flang-commits] [flang] [flang] Record the position of a labeled program-unit END statement (PR #217842)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Fri Aug 21 06:30:15 PDT 2026
================
@@ -0,0 +1,77 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Every labeled statement records its own source position, so a diagnostic
+! about the label is reported on that statement. The position of a labeled
+! END statement of a program unit is the case worth pinning: label analysis
+! visits it in advance, before the statement visitor reaches it, so the
+! position has to be supplied explicitly rather than taken from the visitor's
+! current position. Without that, the diagnostic below has no location at all.
+!
+! `write(*,fmt=L)` names L as a format; every statement here is something other
+! than a FORMAT statement, so each one is reported.
+
+subroutine construct_stmts(n)
+ integer :: n
+
+ write(*,fmt=10)
+ write(*,fmt=11)
+ write(*,fmt=12)
+ write(*,fmt=40)
+
+ ! Statement that begins a construct.
+ !ERROR: '10' not a FORMAT
+10 if (n > 0) then
+ end if
+
+ !ERROR: '11' not a FORMAT
+11 do n = 1, 2
+ end do
+
+ !ERROR: '12' not a FORMAT
+12 select case (n)
+ case default
+ end select
+
+ ! END IF and END SELECT: the label is not in the last part or case. The
+ ! reference sits inside the construct, where naming its END statement is
+ ! permitted, so that only the position is under test here.
+ if (n > 0) then
+ write(*,fmt=20)
+ !ERROR: '20' not a FORMAT
+20 end if
+
+ select case (n)
+ case default
+ write(*,fmt=21)
+ !ERROR: '21' not a FORMAT
+21 end select
+
+ ! Statement that ends a construct.
+ do n = 1, 2
+ write(*,fmt=30)
+ !ERROR: '30' not a FORMAT
+30 end do
+
+ ! Ordinary executable statement.
+ !ERROR: '40' not a FORMAT
+40 continue
+end subroutine
+
+! Labeled END statement of a subroutine.
+subroutine end_subroutine()
+ write(*,fmt=50)
+!ERROR: '50' not a FORMAT
+50 end subroutine
+
+! Labeled END statement of a function.
+function end_function()
+ integer :: end_function
+ end_function = 0
+ write(*,fmt=51)
+!ERROR: '51' not a FORMAT
+51 end function
+
+! Labeled END statement of the main program.
+program end_program
+ write(*,fmt=52)
+!ERROR: '52' not a FORMAT
+52 end program
----------------
eugeneepshteyn wrote:
The fix also changes *which* diagnostic fires for a labeled DO "terminated" by a program-unit END — worth pinning here, since the recorded position feeds the lexical-order comparison in `CheckLabelDoConstraints`, i.e. control flow, not just the message location:
```fortran
subroutine s()
integer :: i
do 50 i = 1, 3
print *, i
50 end subroutine
```
Before (`flang -fc1 -fsyntax-only`) — factually wrong, since label 50 does follow the DO statement:
```console
error: Label '50' doesn't lexically follow DO stmt
```
After — accurate, and anchored on the END statement:
```console
error: This statement cannot terminate the DO loop
```
Suggested addition (verified to pass with this PR and fail without it):
```fortran
! A labeled program-unit END as the terminal statement of a labeled DO
! construct: the recorded position feeds the lexical-order check, so this
! used to be misreported as "Label '54' doesn't lexically follow DO stmt".
subroutine do_terminal()
integer :: i
do 54 i = 1, 3
print *, i
!ERROR: This statement cannot terminate the DO loop
54 end subroutine
```
https://github.com/llvm/llvm-project/pull/217842
More information about the flang-commits
mailing list