aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2023-07-18 14:53:21 -0700
committerPeter Klausler <pklausler@nvidia.com>2023-07-21 12:26:35 -0700
commit01c38ab7a2ead5894d91e7f56634ffad9a9a94a4 (patch)
tree91d21ecc2d34b17f9583fcd77b1d28f5e211b5a6 /flang
parent413c119c6a812f91e480c4a67df512e340c41ff3 (diff)
downloadllvm-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.cpp9
-rw-r--r--flang/test/Semantics/typeinfo04.f9026
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