diff options
author | Peter Klausler <pklausler@nvidia.com> | 2023-07-18 14:53:21 -0700 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2023-07-21 12:26:35 -0700 |
commit | 01c38ab7a2ead5894d91e7f56634ffad9a9a94a4 (patch) | |
tree | 91d21ecc2d34b17f9583fcd77b1d28f5e211b5a6 /flang | |
parent | 413c119c6a812f91e480c4a67df512e340c41ff3 (diff) | |
download | llvm-01c38ab7a2ead5894d91e7f56634ffad9a9a94a4.zip llvm-01c38ab7a2ead5894d91e7f56634ffad9a9a94a4.tar.gz llvm-01c38ab7a2ead5894d91e7f56634ffad9a9a94a4.tar.bz2 |
[flang] Finalize &/or destroy ABSTRACT types
The runtime type information tables always flag ABSTRACT types as
needing neither destruction in general nor finalization in particular.
This is incorrect. Although an ABSTRACT type may not itself have
a FINAL procedure -- its argument cannot be polymorphic, but
ABSTRACT types in declarations must always be so -- it can still
have finalizable components &/or components requiring deallocation.
Differential Revision: https://reviews.llvm.org/D155965
Diffstat (limited to 'flang')
-rw-r--r-- | flang/lib/Semantics/runtime-type-info.cpp | 9 | ||||
-rw-r--r-- | flang/test/Semantics/typeinfo04.f90 | 26 |
2 files changed, 29 insertions, 6 deletions
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp index a6b8d64..cfce8c2 100644 --- a/flang/lib/Semantics/runtime-type-info.cpp +++ b/flang/lib/Semantics/runtime-type-info.cpp @@ -572,8 +572,7 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) { 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<evaluate::StructureConstructor> bindings{ DescribeBindings(dtScope, scope)}; AddValue(dtValues, derivedTypeSchema_, bindingDescCompName, @@ -630,12 +629,10 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) { !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<ObjectEntityDetails>().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 index 0000000..de84643 --- /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 |