[flang-commits] [flang] [flang] Ignore -fno-realloc-lhs for polymorphic allocatable LHS with warning (PR #192697)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Fri Apr 17 09:52:29 PDT 2026
https://github.com/eugeneepshteyn created https://github.com/llvm/llvm-project/pull/192697
When -fno-realloc-lhs is specified and the LHS of an assignment is a polymorphic allocatable (class(*) or class(T)), reallocation semantics are required by the Fortran 2003 standard for dynamic type tracking and cannot be safely skipped. Previously, the compiler generated invalid FIR in such cases (type mismatch between i32 and
!fir.class<!fir.heap<none>>), causing a compilation error.
With this change, when -fno-realloc-lhs is in effect and a polymorphic allocatable LHS is detected, the compiler emits a warning that the option is being ignored for that assignment and proceeds with reallocation semantics.
>From dad003517f01faf824eff2915d2951f755e29cb8 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Fri, 17 Apr 2026 12:48:58 -0400
Subject: [PATCH] [flang] Ignore -fno-realloc-lhs for polymorphic allocatable
LHS with warning
When -fno-realloc-lhs is specified and the LHS of an assignment is a
polymorphic allocatable (class(*) or class(T)), reallocation semantics
are required by the Fortran 2003 standard for dynamic type tracking and
cannot be safely skipped. Previously, the compiler generated invalid
FIR in such cases (type mismatch between i32 and
!fir.class<!fir.heap<none>>), causing a compilation error.
With this change, when -fno-realloc-lhs is in effect and a polymorphic
allocatable LHS is detected, the compiler emits a warning that the
option is being ignored for that assignment and proceeds with
reallocation semantics.
---
flang/lib/Lower/Bridge.cpp | 24 +++++++++++++++++++-----
flang/test/Lower/reallocate-lhs.f90 | 20 ++++++++++++++++++--
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 28c82a6ca99ce..2153c07e03020 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -5592,15 +5592,29 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// Gather some information about the assignment that will impact how it is
// lowered.
- const bool isWholeAllocatableAssignment =
+ const bool lhsIsWholeAllocatable =
!userDefinedAssignment && !isInsideHlfirWhere() &&
- Fortran::lower::isWholeAllocatable(assign.lhs) &&
- bridge.getLoweringOptions().getReallocateLHS();
+ Fortran::lower::isWholeAllocatable(assign.lhs);
+ std::optional<Fortran::evaluate::DynamicType> lhsType =
+ assign.lhs.GetType();
+ // Polymorphic allocatable LHS always requires reallocation semantics
+ // regardless of -fno-realloc-lhs: assignment to a polymorphic variable
+ // is a F2003+ feature that requires dynamic type tracking, which cannot
+ // be safely skipped. When -fno-realloc-lhs is specified but the LHS is
+ // polymorphic, emit a warning and proceed with reallocation semantics.
+ const bool lhsIsPolymorphic =
+ lhsType.has_value() && lhsType->IsPolymorphic();
+ if (lhsIsWholeAllocatable && lhsIsPolymorphic &&
+ !bridge.getLoweringOptions().getReallocateLHS())
+ mlir::emitWarning(loc,
+ "-fno-realloc-lhs is ignored for assignment to "
+ "polymorphic allocatable");
+ const bool isWholeAllocatableAssignment =
+ lhsIsWholeAllocatable &&
+ (bridge.getLoweringOptions().getReallocateLHS() || lhsIsPolymorphic);
const bool isUserDefAssignToPointerOrAllocatable =
userDefinedAssignment &&
firstDummyIsPointerOrAllocatable(*userDefinedAssignment);
- std::optional<Fortran::evaluate::DynamicType> lhsType =
- assign.lhs.GetType();
const bool keepLhsLengthInAllocatableAssignment =
isWholeAllocatableAssignment && lhsType.has_value() &&
lhsType->category() == Fortran::common::TypeCategory::Character &&
diff --git a/flang/test/Lower/reallocate-lhs.f90 b/flang/test/Lower/reallocate-lhs.f90
index 82a4edab787c7..7b65d6b6a9741 100644
--- a/flang/test/Lower/reallocate-lhs.f90
+++ b/flang/test/Lower/reallocate-lhs.f90
@@ -1,9 +1,13 @@
! RUN: bbc %s -o - -emit-hlfir | FileCheck %s --check-prefixes=ALL,REALLOCLHS
! RUN: bbc %s -o - -emit-hlfir -frealloc-lhs | FileCheck %s --check-prefixes=ALL,REALLOCLHS
-! RUN: bbc %s -o - -emit-hlfir -frealloc-lhs=false | FileCheck %s --check-prefixes=ALL,NOREALLOCLHS
+! RUN: bbc %s -o - -emit-hlfir -frealloc-lhs=false 2>&1 | FileCheck %s --check-prefixes=ALL,NOREALLOCLHS,POLYWARNING
! RUN: %flang_fc1 %s -o - -emit-hlfir | FileCheck %s --check-prefixes=ALL,REALLOCLHS
! RUN: %flang_fc1 %s -o - -emit-hlfir -frealloc-lhs | FileCheck %s --check-prefixes=ALL,REALLOCLHS
-! RUN: %flang_fc1 %s -o - -emit-hlfir -fno-realloc-lhs | FileCheck %s --check-prefixes=ALL,NOREALLOCLHS
+! RUN: %flang_fc1 %s -o - -emit-hlfir -fno-realloc-lhs 2>&1 | FileCheck %s --check-prefixes=ALL,NOREALLOCLHS,POLYWARNING
+
+! -fno-realloc-lhs must be ignored for polymorphic allocatable LHS (test3 below).
+! The warning below is emitted before the MLIR output, so it must be checked first.
+! POLYWARNING: warning: {{.*}}-fno-realloc-lhs is ignored for assignment to polymorphic allocatable left-hand side
subroutine test1(a, b)
integer, allocatable :: a(:), b(:)
@@ -30,3 +34,15 @@ end subroutine test2
! NOREALLOCLHS: %[[VAL_7:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
! NOREALLOCLHS: hlfir.assign %{{.*}} to %[[VAL_7]] : !fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
+! Polymorphic allocatable LHS: reallocation semantics must be used regardless of
+! -fno-realloc-lhs, because the Fortran standard requires dynamic type tracking
+! for polymorphic assignments (a F2003+ feature that cannot be safely skipped).
+subroutine test3(x)
+ class(*), allocatable :: x
+ x = 1
+end subroutine test3
+
+! ALL-LABEL: func.func @_QPtest3(
+! ALL: %[[VAL_1:.*]]:2 = hlfir.declare{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest3Ex"}
+! ALL: hlfir.assign %{{.*}} to %[[VAL_1]]#0 realloc : i32, !fir.ref<!fir.class<!fir.heap<none>>>
+
More information about the flang-commits
mailing list