diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp --- a/flang/lib/Semantics/runtime-type-info.cpp +++ b/flang/lib/Semantics/runtime-type-info.cpp @@ -572,8 +572,7 @@ procPtrComponents.size())})); // Compile the "vtable" of type-bound procedure bindings std::uint32_t specialBitSet{0}; - bool isAbstractType{dtSymbol->attrs().test(Attr::ABSTRACT)}; - if (!isAbstractType) { + if (!dtSymbol->attrs().test(Attr::ABSTRACT)) { std::vector bindings{ DescribeBindings(dtScope, scope)}; AddValue(dtValues, derivedTypeSchema_, bindingDescCompName, @@ -630,12 +629,10 @@ !derivedTypeSpec->HasDefaultInitialization(false, false))); // Similarly, a flag to short-circuit destruction when not needed. AddValue(dtValues, derivedTypeSchema_, "nodestructionneeded"s, - IntExpr<1>(isAbstractType || - (derivedTypeSpec && !derivedTypeSpec->HasDestruction()))); + IntExpr<1>(derivedTypeSpec && !derivedTypeSpec->HasDestruction())); // Similarly, a flag to short-circuit finalization when not needed. AddValue(dtValues, derivedTypeSchema_, "nofinalizationneeded"s, - IntExpr<1>(isAbstractType || - (derivedTypeSpec && !IsFinalizable(*derivedTypeSpec)))); + IntExpr<1>(derivedTypeSpec && !IsFinalizable(*derivedTypeSpec))); } dtObject.get().set_init(MaybeExpr{ StructureExpr(Structure(derivedTypeSchema_, std::move(dtValues)))}); diff --git a/flang/test/Semantics/typeinfo04.f90 b/flang/test/Semantics/typeinfo04.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/typeinfo04.f90 @@ -0,0 +1,26 @@ +!RUN: bbc --dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s +! Ensure ABSTRACT types are properly marked for finalization &/or +! destruction. +module m + type :: finalizable + contains + final :: final + end type +!CHECK: .dt.finalizable, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.finalizable,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.finalizable,specialbitset=128_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) + type, abstract :: t1 + end type +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t1,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) + type, abstract :: t2 + real, allocatable :: a(:) + end type +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t2,sizeinbytes=48_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) + type, abstract :: t3 + type(finalizable) :: x + end type +!CHECK: .dt.t3, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t3,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t3,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) + contains + impure elemental subroutine final(x) + type(finalizable), intent(in out) :: x + end +end