Skip to content

Commit 25822dc

Browse files
authored
[flang] Fix searches for polymorphic components (#102212)
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.
1 parent 7c512ce commit 25822dc

File tree

6 files changed

+42
-11
lines changed

6 files changed

+42
-11
lines changed

flang/include/flang/Semantics/tools.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,18 @@ std::list<std::list<SymbolRef>> GetStorageAssociations(const Scope &);
442442
// closure of its components (including POINTERs) and the
443443
// PotentialAndPointer subobject components of its non-POINTER derived type
444444
// components.
445+
//
446+
// type t1 ultimate components: x, a, p
447+
// real x direct components: x, a, p
448+
// real, allocatable :: a potential components: x, a
449+
// real, pointer :: p potential & pointers: x, a, p
450+
// end type
451+
// type t2 ultimate components: y, c%x, c%a, c%p, b
452+
// real y direct components: y, c, c%x, c%a, c%p, b
453+
// type(t1) :: c potential components: y, c, c%x, c%a, b, b%x, b%a
454+
// type(t1), allocatable :: b potential & pointers: potentials + c%p + b%p
455+
// end type
456+
//
445457
// Parent and procedure components are considered against these definitions.
446458
// For this kind of iterator, the component tree is recursively visited in the
447459
// following order:
@@ -620,8 +632,8 @@ UltimateComponentIterator::const_iterator FindAllocatableUltimateComponent(
620632
const DerivedTypeSpec &);
621633
DirectComponentIterator::const_iterator FindAllocatableOrPointerDirectComponent(
622634
const DerivedTypeSpec &);
623-
UltimateComponentIterator::const_iterator
624-
FindPolymorphicAllocatableUltimateComponent(const DerivedTypeSpec &);
635+
PotentialComponentIterator::const_iterator
636+
FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &);
625637

626638
// The LabelEnforce class (given a set of labels) provides an error message if
627639
// there is a branch to a label which is not in the given set.

flang/lib/Semantics/check-declarations.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,10 @@ void CheckHelper::Check(const Symbol &symbol) {
405405
messages_.Say(
406406
"Result of pure function may not have an impure FINAL subroutine"_err_en_US);
407407
}
408-
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
408+
if (auto bad{
409+
FindPolymorphicAllocatablePotentialComponent(*derived)}) {
409410
SayWithDeclaration(*bad,
410-
"Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'"_err_en_US,
411+
"Result of pure function may not have polymorphic ALLOCATABLE potential component '%s'"_err_en_US,
411412
bad.BuildResultDesignatorName());
412413
}
413414
}

flang/lib/Semantics/definable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ static std::optional<parser::Message> WhyNotDefinableLast(parser::CharBlock at,
223223
}
224224
if (const DerivedTypeSpec * derived{GetDerivedTypeSpec(dyType)}) {
225225
if (!flags.test(DefinabilityFlag::PolymorphicOkInPure)) {
226-
if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
226+
if (auto bad{
227+
FindPolymorphicAllocatablePotentialComponent(*derived)}) {
227228
return BlameSymbol(at,
228229
"'%s' has polymorphic component '%s' in a pure subprogram"_en_US,
229230
original, bad.BuildResultDesignatorName());

flang/lib/Semantics/tools.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ const Symbol *HasImpureFinal(const Symbol &original, std::optional<int> rank) {
866866

867867
bool MayRequireFinalization(const DerivedTypeSpec &derived) {
868868
return IsFinalizable(derived) ||
869-
FindPolymorphicAllocatableUltimateComponent(derived);
869+
FindPolymorphicAllocatablePotentialComponent(derived);
870870
}
871871

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

1407-
UltimateComponentIterator::const_iterator
1408-
FindPolymorphicAllocatableUltimateComponent(const DerivedTypeSpec &derived) {
1409-
UltimateComponentIterator ultimates{derived};
1407+
PotentialComponentIterator::const_iterator
1408+
FindPolymorphicAllocatablePotentialComponent(const DerivedTypeSpec &derived) {
1409+
PotentialComponentIterator potentials{derived};
14101410
return std::find_if(
1411-
ultimates.begin(), ultimates.end(), IsPolymorphicAllocatable);
1411+
potentials.begin(), potentials.end(), IsPolymorphicAllocatable);
14121412
}
14131413

14141414
const Symbol *FindUltimateComponent(const DerivedTypeSpec &derived,

flang/test/Semantics/call10.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pure function f07() ! C1585
7878
class(t), allocatable :: f07
7979
end function
8080
pure function f08() ! C1585
81-
!ERROR: Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%a'
81+
!ERROR: Result of pure function may not have polymorphic ALLOCATABLE potential component '%a'
8282
type(polyAlloc) :: f08
8383
end function
8484

flang/test/Semantics/typeinfo11.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
!RUN: bbc --dump-symbols %s | FileCheck %s
2+
!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s
3+
4+
!Tests that derived types with polymorphic potential subobject
5+
!components do not have their noFinalizationNeeded flags set, even
6+
!when those components are packaged within another allocatable.
7+
8+
type t1
9+
class(*), allocatable :: a
10+
end type
11+
type t2
12+
type(t1), allocatable :: b
13+
end type
14+
type(t2) x
15+
end
16+
17+
!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 commit comments

Comments
 (0)