Skip to content

Commit 43abd25

Browse files
authored
[flang] Fix corner case of defined component assignment (#142201)
For componentwise assignment in derived type intrinsic assignment, the runtime type information's special binding table is currently populated only with type-bound ASSIGNMENT(=) procedures that have the same derived type for both arguments. This restriction excludes all defined assignments for cases that cannot arise in this context, like defined assignments from intrinsic types or incompatible derived types. However, this restriction also excludes defined assignments from distinct but compatible derived types, i.e. ancestors. Loosen it a little to allow them. Fixes #142151.
1 parent f521338 commit 43abd25

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

flang/lib/Semantics/runtime-type-info.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,10 +1121,10 @@ void RuntimeTableBuilder::DescribeSpecialProc(
11211121
int argThatMightBeDescriptor{0};
11221122
MaybeExpr which;
11231123
if (isAssignment) {
1124-
// Only type-bound asst's with the same type on both dummy arguments
1124+
// Only type-bound asst's with compatible types on both dummy arguments
11251125
// are germane to the runtime, which needs only these to implement
11261126
// component assignment as part of intrinsic assignment.
1127-
// Non-type-bound generic INTERFACEs and assignments from distinct
1127+
// Non-type-bound generic INTERFACEs and assignments from incompatible
11281128
// types must not be used for component intrinsic assignment.
11291129
CHECK(proc->dummyArguments.size() == 2);
11301130
const auto t1{
@@ -1137,8 +1137,12 @@ void RuntimeTableBuilder::DescribeSpecialProc(
11371137
.type.type()};
11381138
if (!binding || t1.category() != TypeCategory::Derived ||
11391139
t2.category() != TypeCategory::Derived ||
1140-
t1.IsUnlimitedPolymorphic() || t2.IsUnlimitedPolymorphic() ||
1141-
t1.GetDerivedTypeSpec() != t2.GetDerivedTypeSpec()) {
1140+
t1.IsUnlimitedPolymorphic() || t2.IsUnlimitedPolymorphic()) {
1141+
return;
1142+
}
1143+
if (!derivedTypeSpec ||
1144+
!derivedTypeSpec->MatchesOrExtends(t1.GetDerivedTypeSpec()) ||
1145+
!derivedTypeSpec->MatchesOrExtends(t2.GetDerivedTypeSpec())) {
11421146
return;
11431147
}
11441148
which = proc->IsElemental() ? elementalAssignmentEnum_

flang/test/Semantics/typeinfo01.f90

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ module m06
7373
end type
7474
type, extends(t) :: t2
7575
contains
76-
procedure :: s1 => s2 ! override
76+
procedure :: s1 => s2
7777
end type
7878
contains
7979
subroutine s1(x, y)
@@ -86,8 +86,37 @@ subroutine s2(x, y)
8686
end subroutine
8787
!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
8888
!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1)
89-
!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1)
89+
!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1)
9090
!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1)]
91+
!CHECK: .s.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s2)]
92+
!CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)]
93+
!CHECK: .v.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s2,name=.n.s1)]
94+
end module
95+
96+
module m06a
97+
type :: t
98+
contains
99+
procedure, pass(y) :: s1
100+
generic :: assignment(=) => s1
101+
end type
102+
type, extends(t) :: t2
103+
contains
104+
procedure, pass(y) :: s1 => s2
105+
end type
106+
contains
107+
subroutine s1(x, y)
108+
class(t), intent(out) :: x
109+
class(t), intent(in) :: y
110+
end subroutine
111+
subroutine s2(x, y)
112+
class(t), intent(out) :: x
113+
class(t2), intent(in) :: y
114+
end subroutine
115+
!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
116+
!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1)
117+
!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1)
118+
!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1)]
119+
!CHECK: .s.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s2)]
91120
!CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)]
92121
!CHECK: .v.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s2,name=.n.s1)]
93122
end module

0 commit comments

Comments
 (0)