Skip to content

Commit

Permalink
[flang] Fix searches for polymorphic components (llvm#102212)
Browse files Browse the repository at this point in the history
FindPolymorphicAllocatableUltimateComponent needs to be
FindPolymorphicAllocatablePotentialComponent. The current search is
missing cases where a derived type has an allocatable component whose
type has a polymorphic allocatable component.
  • Loading branch information
klausler authored Aug 8, 2024
1 parent 7c512ce commit 25822dc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 11 deletions.
16 changes: 14 additions & 2 deletions flang/include/flang/Semantics/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,18 @@ std::list<std::list<SymbolRef>> GetStorageAssociations(const Scope &);
// closure of its components (including POINTERs) and the
// PotentialAndPointer subobject components of its non-POINTER derived type
// components.
//
// type t1 ultimate components: x, a, p
// real x direct components: x, a, p
// real, allocatable :: a potential components: x, a
// real, pointer :: p potential & pointers: x, a, p
// end type
// type t2 ultimate components: y, c%x, c%a, c%p, b
// real y direct components: y, c, c%x, c%a, c%p, b
// type(t1) :: c potential components: y, c, c%x, c%a, b, b%x, b%a
// type(t1), allocatable :: b potential & pointers: potentials + c%p + b%p
// end type
//
// Parent and procedure components are considered against these definitions.
// For this kind of iterator, the component tree is recursively visited in the
// following order:
Expand Down Expand Up @@ -620,8 +632,8 @@ UltimateComponentIterator::const_iterator FindAllocatableUltimateComponent(
const DerivedTypeSpec &);
DirectComponentIterator::const_iterator FindAllocatableOrPointerDirectComponent(
const DerivedTypeSpec &);
UltimateComponentIterator::const_iterator
FindPolymorphicAllocatableUltimateComponent(const DerivedTypeSpec &);
PotentialComponentIterator::const_iterator
FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &);

// The LabelEnforce class (given a set of labels) provides an error message if
// there is a branch to a label which is not in the given set.
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,10 @@ void CheckHelper::Check(const Symbol &symbol) {
messages_.Say(
"Result of pure function may not have an impure FINAL subroutine"_err_en_US);
}
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
if (auto bad{
FindPolymorphicAllocatablePotentialComponent(*derived)}) {
SayWithDeclaration(*bad,
"Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'"_err_en_US,
"Result of pure function may not have polymorphic ALLOCATABLE potential component '%s'"_err_en_US,
bad.BuildResultDesignatorName());
}
}
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/definable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ static std::optional<parser::Message> WhyNotDefinableLast(parser::CharBlock at,
}
if (const DerivedTypeSpec * derived{GetDerivedTypeSpec(dyType)}) {
if (!flags.test(DefinabilityFlag::PolymorphicOkInPure)) {
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
if (auto bad{
FindPolymorphicAllocatablePotentialComponent(*derived)}) {
return BlameSymbol(at,
"'%s' has polymorphic component '%s' in a pure subprogram"_en_US,
original, bad.BuildResultDesignatorName());
Expand Down
10 changes: 5 additions & 5 deletions flang/lib/Semantics/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ const Symbol *HasImpureFinal(const Symbol &original, std::optional<int> rank) {

bool MayRequireFinalization(const DerivedTypeSpec &derived) {
return IsFinalizable(derived) ||
FindPolymorphicAllocatableUltimateComponent(derived);
FindPolymorphicAllocatablePotentialComponent(derived);
}

bool HasAllocatableDirectComponent(const DerivedTypeSpec &derived) {
Expand Down Expand Up @@ -1404,11 +1404,11 @@ DirectComponentIterator::const_iterator FindAllocatableOrPointerDirectComponent(
return std::find_if(directs.begin(), directs.end(), IsAllocatableOrPointer);
}

UltimateComponentIterator::const_iterator
FindPolymorphicAllocatableUltimateComponent(const DerivedTypeSpec &derived) {
UltimateComponentIterator ultimates{derived};
PotentialComponentIterator::const_iterator
FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &derived) {
PotentialComponentIterator potentials{derived};
return std::find_if(
ultimates.begin(), ultimates.end(), IsPolymorphicAllocatable);
potentials.begin(), potentials.end(), IsPolymorphicAllocatable);
}

const Symbol *FindUltimateComponent(const DerivedTypeSpec &derived,
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Semantics/call10.f90
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pure function f07() ! C1585
class(t), allocatable :: f07
end function
pure function f08() ! C1585
!ERROR: Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%a'
!ERROR: Result of pure function may not have polymorphic ALLOCATABLE potential component '%a'
type(polyAlloc) :: f08
end function

Expand Down
17 changes: 17 additions & 0 deletions flang/test/Semantics/typeinfo11.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
!RUN: bbc --dump-symbols %s | FileCheck %s
!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s

!Tests that derived types with polymorphic potential subobject
!components do not have their noFinalizationNeeded flags set, even
!when those components are packaged within another allocatable.

type t1
class(*), allocatable :: a
end type
type t2
type(t1), allocatable :: b
end type
type(t2) x
end

!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1)

0 comments on commit 25822dc

Please sign in to comment.