[flang-commits] [flang] [flang] Fix crash in defined I/O table creation (PR #173783)

via flang-commits flang-commits at lists.llvm.org
Sun Dec 28 07:51:02 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

The code that handles non-type-bound defined I/O for sequence types didn't allow for the type to be shadowed in its scope by a homonymous generic procedure interface.

Fixes https://github.com/llvm/llvm-project/issues/173766.

---
Full diff: https://github.com/llvm/llvm-project/pull/173783.diff


2 Files Affected:

- (modified) flang/lib/Semantics/runtime-type-info.cpp (+13-7) 
- (added) flang/test/Lower/bug173766.f90 (+28) 


``````````diff
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index bbaded36c62e3..8f92fda65685a 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -1394,13 +1394,19 @@ CollectNonTbpDefinedIoGenericInterfaces(
               // scope has an equivalent type, use it for the table rather
               // than the "dtv" argument's type.
               if (const Symbol *inScope{scope.FindSymbol(derived.name())}) {
-                const Symbol &ultimate{inScope->GetUltimate()};
-                DerivedTypeSpec localDerivedType{inScope->name(), ultimate};
-                if (ultimate.has<DerivedTypeDetails>() &&
-                    evaluate::DynamicType{derived, /*isPolymorphic=*/false}
-                        .IsTkCompatibleWith(evaluate::DynamicType{
-                            localDerivedType, /*iP=*/false})) {
-                  derivedScope = ultimate.scope();
+                const Symbol *localDerived{&inScope->GetUltimate()};
+                if (const auto *generic{
+                        localDerived->detailsIf<GenericDetails>()}) {
+                  localDerived = generic->derivedType();
+                }
+                if (localDerived && localDerived->has<DerivedTypeDetails>()) {
+                  DerivedTypeSpec localDerivedType{
+                      inScope->name(), *localDerived};
+                  if (evaluate::DynamicType{derived, /*isPolymorphic=*/false}
+                          .IsTkCompatibleWith(evaluate::DynamicType{
+                              localDerivedType, /*iP=*/false})) {
+                    derivedScope = localDerived->scope();
+                  }
                 }
               }
             }
diff --git a/flang/test/Lower/bug173766.f90 b/flang/test/Lower/bug173766.f90
new file mode 100644
index 0000000000000..a9705f144c563
--- /dev/null
+++ b/flang/test/Lower/bug173766.f90
@@ -0,0 +1,28 @@
+!RUN: bbc -emit-fir -o - %s 2>&1 | FileCheck %s
+module m
+  type samename
+    sequence
+    integer n
+  end type
+  interface samename
+  end interface
+  interface write(formatted)
+    module procedure :: write_formatted
+  end interface
+ contains
+  subroutine write_formatted(t, unit, iotype, v_list, iostat, iomsg)
+    type(samename), intent(in) :: t
+    integer, intent(in) :: unit
+    character(len=*), intent(in) :: iotype
+    integer, intent(in) :: v_list(:)
+    integer, intent(out) :: iostat
+    character(len=*), intent(inout) :: iomsg
+  end
+  subroutine test
+    print *, samename(123)
+  end
+end
+
+!CHECK: %[[VAL_8:.*]] = fir.address_of(@_QQMmFtest.nonTbpDefinedIoTable) : !fir.ref<tuple<i64, !fir.ref<!fir.array<1xtuple<!fir.ref<none>, !fir.ref<none>, i32, i8>>>, i1>>
+!CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<tuple<i64, !fir.ref<!fir.array<1xtuple<!fir.ref<none>, !fir.ref<none>, i32, i8>>>, i1>>) -> !fir.ref<none>
+!CHECK: %{{.*}} = fir.call @_FortranAioOutputDerivedType(%{{.*}}, %{{.*}}, %[[VAL_9]]) fastmath<contract> : (!fir.ref<i8>, !fir.box<none>, !fir.ref<none>) -> i1

``````````

</details>


https://github.com/llvm/llvm-project/pull/173783


More information about the flang-commits mailing list