diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -186,6 +186,7 @@ bool HasCoarray(const parser::Expr &); bool IsAssumedType(const Symbol &); bool IsPolymorphic(const Symbol &); +bool IsUnlimitedPolymorphic(const Symbol &); bool IsPolymorphicAllocatable(const Symbol &); // Return an error if a symbol is not accessible from a scope diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -625,6 +625,11 @@ return false; if (Fortran::semantics::IsDummy(sym) && !Fortran::semantics::IsIntentOut(sym)) return false; + // Unlimited polymorphic intent(out) dummy might need default initialization + // at runtime but it cannot be determined for sure here. + if (Fortran::semantics::IsUnlimitedPolymorphic(sym) && + Fortran::semantics::IsDummy(sym) && Fortran::semantics::IsIntentOut(sym)) + return true; // Local variables (including function results), and intent(out) dummies must // be default initialized at runtime if their type has default initialization. return hasDefaultInitialization(sym); diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -961,6 +961,13 @@ return false; } +bool IsUnlimitedPolymorphic(const Symbol &symbol) { + if (const DeclTypeSpec * type{symbol.GetType()}) { + return type->IsUnlimitedPolymorphic(); + } + return false; +} + bool IsPolymorphicAllocatable(const Symbol &symbol) { return IsAllocatable(symbol) && IsPolymorphic(symbol); } diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -738,6 +738,15 @@ ! CHECK: %[[RES:.*]] = fir.call @_QMpolymorphic_testPunlimited_polymorphic_alloc_array_ret() fastmath : () -> !fir.class>> ! CHECK: fir.save_result %[[RES]] to %[[RES_TMP]] : !fir.class>>, !fir.ref>>> + subroutine test_unlimited_polymorphic_intentout(a) + class(*), intent(out) :: a + end subroutine + +! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_unlimited_polymorphic_intentout( +! CHECK-SAME: %[[ARG0:.*]]: !fir.class {fir.bindc_name = "a"}) { +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class) -> !fir.box +! CHECK: %{{.*}} = fir.call @_FortranAInitialize(%[[BOX_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.box, !fir.ref, i32) -> none + end module program test