Skip to content

Commit d46c639

Browse files
authored
[flang] Fix derived type compatibility checking in ALLOCATE (llvm#102035)
The derived type compatibility checking for ALLOCATE statements with SOURCE= or MOLD= was only checking for the same derived type name. That is a necessary but not sufficient check, and it can produce bogus errors as well as miss valid errors. Fixes llvm#101909.
1 parent d9af9cf commit d46c639

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

flang/include/flang/Evaluate/type.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,9 @@ bool IsCUDAIntrinsicType(const DynamicType &);
494494
// Determine whether two derived type specs are sufficiently identical
495495
// to be considered the "same" type even if declared separately.
496496
bool AreSameDerivedType(
497-
const semantics::DerivedTypeSpec &x, const semantics::DerivedTypeSpec &y);
497+
const semantics::DerivedTypeSpec &, const semantics::DerivedTypeSpec &);
498+
bool AreSameDerivedTypeIgnoringTypeParameters(
499+
const semantics::DerivedTypeSpec &, const semantics::DerivedTypeSpec &);
498500

499501
// For generating "[extern] template class", &c. boilerplate
500502
#define EXPAND_FOR_EACH_INTEGER_KIND(M, P, S) \

flang/lib/Evaluate/type.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,13 @@ bool AreSameDerivedType(
505505
return AreSameDerivedType(x, y, false, false, inProgress);
506506
}
507507

508-
bool AreSameDerivedType(
508+
bool AreSameDerivedTypeIgnoringTypeParameters(
509+
const semantics::DerivedTypeSpec &x, const semantics::DerivedTypeSpec &y) {
510+
SetOfDerivedTypePairs inProgress;
511+
return AreSameDerivedType(x, y, true, true, inProgress);
512+
}
513+
514+
static bool AreSameDerivedType(
509515
const semantics::DerivedTypeSpec *x, const semantics::DerivedTypeSpec *y) {
510516
return x == y || (x && y && AreSameDerivedType(*x, *y));
511517
}

flang/lib/Semantics/check-allocate.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,13 @@ static bool IsTypeCompatible(
270270
const DeclTypeSpec &type1, const DerivedTypeSpec &derivedType2) {
271271
if (const DerivedTypeSpec * derivedType1{type1.AsDerived()}) {
272272
if (type1.category() == DeclTypeSpec::Category::TypeDerived) {
273-
return &derivedType1->typeSymbol() == &derivedType2.typeSymbol();
273+
return evaluate::AreSameDerivedTypeIgnoringTypeParameters(
274+
*derivedType1, derivedType2);
274275
} else if (type1.category() == DeclTypeSpec::Category::ClassDerived) {
275276
for (const DerivedTypeSpec *parent{&derivedType2}; parent;
276277
parent = parent->typeSymbol().GetParentTypeSpec()) {
277-
if (&derivedType1->typeSymbol() == &parent->typeSymbol()) {
278+
if (evaluate::AreSameDerivedTypeIgnoringTypeParameters(
279+
*derivedType1, *parent)) {
278280
return true;
279281
}
280282
}

flang/test/Semantics/allocate08.f90

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,42 @@ subroutine bar
9595
end subroutine
9696
end module
9797

98+
module mod1
99+
type, bind(C) :: t
100+
integer :: n
101+
end type
102+
type(t), allocatable :: x
103+
end
104+
105+
module mod2
106+
type, bind(C) :: t
107+
integer :: n
108+
end type
109+
type(t), allocatable :: x
110+
end
111+
112+
module mod3
113+
type, bind(C) :: t
114+
real :: a
115+
end type
116+
type(t), allocatable :: x
117+
end
118+
119+
subroutine same_type
120+
use mod1, only: a => x
121+
use mod2, only: b => x
122+
use mod3, only: c => x
123+
allocate(a)
124+
allocate(b, source=a) ! ok
125+
deallocate(a)
126+
allocate(a, source=b) ! ok
127+
!ERROR: Allocatable object in ALLOCATE must be type compatible with source expression from MOLD or SOURCE
128+
allocate(c, source=a)
129+
deallocate(a)
130+
!ERROR: Allocatable object in ALLOCATE must be type compatible with source expression from MOLD or SOURCE
131+
allocate(a, source=c)
132+
end
133+
98134
! Related to C945, check typeless expression are caught
99135

100136
subroutine sub

0 commit comments

Comments
 (0)