-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[flang] Fix crash in defined I/O table creation #173783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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 llvm#173766.
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Peter Klausler (klausler) ChangesThe 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 #173766. Full diff: https://github.com/llvm/llvm-project/pull/173783.diff 2 Files Affected:
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
|
|
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesThe 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 #173766. Full diff: https://github.com/llvm/llvm-project/pull/173783.diff 2 Files Affected:
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
|
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 #173766.