[flang-commits] [flang] dabd9fe - [flang] Attribute the generated entry point to the main program's start (#223742)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 16 02:23:44 PDT 2026
Author: jiel-nv
Date: 2026-09-16T10:23:38+01:00
New Revision: dabd9fe738cc20e8f4364c7b07a1f7f45d2a537d
URL: https://github.com/llvm/llvm-project/commit/dabd9fe738cc20e8f4364c7b07a1f7f45d2a537d
DIFF: https://github.com/llvm/llvm-project/commit/dabd9fe738cc20e8f4364c7b07a1f7f45d2a537d.diff
LOG: [flang] Attribute the generated entry point to the main program's start (#223742)
The `main` entry point that lowering generates for a Fortran main
program is attributed to the end-stmt of the last function-like unit
that was lowered. e.g.
```fortran
subroutine foo(x)
real :: x
x = x + 1.0
end subroutine foo
program demo
real :: a
a = 1.0
call foo(a)
print *, a
end program demo
```
`PROGRAM` is on line 6 and `end program` on line 11.
The loc info shows up in FIR for the compiler generated C `main`
wrapper:
```
before this PR: } loc("repro.f90":11:1)
after this PR: } loc("repro.f90":6:1)
```
Added:
Modified:
flang/lib/Lower/Bridge.cpp
flang/test/Lower/main_location.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 099035e91e700..5e9550b3ff215 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -531,6 +531,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// - Module variables are lowered once all the function declarations are
// available.
bool hasMainProgram = false;
+ Fortran::parser::CharBlock mainProgramPosition{};
llvm::SmallVector<const Fortran::semantics::Symbol *>
globalOmpRequiresSymbols;
createBuilderOutsideOfFuncOpAndDo([&]() {
@@ -538,8 +539,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::common::visit(
Fortran::common::visitors{
[&](Fortran::lower::pft::FunctionLikeUnit &f) {
- if (f.isMainProgram())
+ if (f.isMainProgram()) {
hasMainProgram = true;
+ mainProgramPosition = f.getStartingSourceLoc();
+ }
declareFunction(f);
globalOmpRequiresSymbols.push_back(f.getScope().symbol());
},
@@ -617,6 +620,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// Generate the `main` entry point if necessary
if (hasMainProgram)
createBuilderOutsideOfFuncOpAndDo([&]() {
+ // Lowering has walked every unit, so the current position is the END
+ // statement of the last one. Reset it to the main program's start.
+ setCurrentPosition(mainProgramPosition);
fir::runtime::genMain(
*builder, toLocation(), bridge.getEnvironmentDefaults(),
(getFoldingContext().languageFeatures().IsEnabled(
diff --git a/flang/test/Lower/main_location.f90 b/flang/test/Lower/main_location.f90
index 73943f845f1ca..31970b3161e92 100644
--- a/flang/test/Lower/main_location.f90
+++ b/flang/test/Lower/main_location.f90
@@ -5,6 +5,9 @@
! Check that the missing optional program-stmt (R1401)
! does not result in unknown source location of the corresponding
! function.
+!
+! Also check that the generated `main` entry point is attributed to the start
+! of the main program unit rather than to its end-stmt.
!--- test1.f90
if (.false.) then
@@ -16,6 +19,9 @@
! TEST1-NEXT: return loc("{{.*}}test1.f90":3:1)
! TEST1-NEXT: } loc("{{.*}}test1.f90":1:1)
+! TEST1: func.func @main(%{{.*}}: i32 loc("{{.*}}test1.f90":1:1)
+! TEST1: } loc("{{.*}}test1.f90":1:1)
+
!--- test2.f90
!!! keep me here
if (.true.) then
@@ -26,3 +32,6 @@
! TEST2-NEXT: fir.dummy_scope : !fir.dscope loc("{{.*}}test2.f90":2:1)
! TEST2-NEXT: return loc("{{.*}}test2.f90":4:1)
! TEST2-NEXT: } loc("{{.*}}test2.f90":2:1)
+
+! TEST2: func.func @main(%{{.*}}: i32 loc("{{.*}}test2.f90":2:1)
+! TEST2: } loc("{{.*}}test2.f90":2:1)
More information about the flang-commits
mailing list