Skip to content

Commit 4228e28

Browse files
authored
[flang] Fix crash in semantics (#106158)
Semantics crashes when merging a USE-associated derived type with a local generic procedure interface of the same name. (The other direction works.)
1 parent 9a2fd97 commit 4228e28

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

flang/lib/Semantics/resolve-names.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -3131,7 +3131,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
31313131
combinedDerivedType = useDerivedType;
31323132
} else {
31333133
const Scope *localScope{localDerivedType->scope()};
3134-
const Scope *useScope{useDerivedType->scope()};
3134+
const Scope *useScope{useDerivedType->GetUltimate().scope()};
31353135
if (localScope && useScope && localScope->derivedTypeSpec() &&
31363136
useScope->derivedTypeSpec() &&
31373137
evaluate::AreSameDerivedType(
@@ -3307,7 +3307,12 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
33073307
AddGenericUse(newUseGeneric, localName, useUltimate);
33083308
newUseGeneric.AddUse(*localSymbol);
33093309
if (combinedDerivedType) {
3310-
newUseGeneric.set_derivedType(*const_cast<Symbol *>(combinedDerivedType));
3310+
if (const auto *oldDT{newUseGeneric.derivedType()}) {
3311+
CHECK(&oldDT->GetUltimate() == &combinedDerivedType->GetUltimate());
3312+
} else {
3313+
newUseGeneric.set_derivedType(
3314+
*const_cast<Symbol *>(combinedDerivedType));
3315+
}
33113316
}
33123317
if (combinedProcedure) {
33133318
newUseGeneric.set_specific(*const_cast<Symbol *>(combinedProcedure));

flang/test/Semantics/generic09.f90

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
module m1
3+
type foo
4+
integer n
5+
integer :: m = 1
6+
end type
7+
end
8+
9+
module m2
10+
use m1
11+
interface foo
12+
module procedure f1
13+
end interface
14+
contains
15+
type(foo) function f1(a)
16+
real, intent(in) :: a
17+
f1%n = a
18+
f1%m = 2
19+
end
20+
end
21+
22+
module m3
23+
use m2
24+
interface foo
25+
module procedure f2
26+
end interface
27+
contains
28+
type(foo) function f2(a)
29+
double precision, intent(in) :: a
30+
f2%n = a
31+
f2%m = 3
32+
end
33+
end
34+
35+
program main
36+
use m3
37+
type(foo) x
38+
!CHECK: foo(n=1_4,m=1_4)
39+
x = foo(1)
40+
print *, x
41+
!CHECK: f1(2._4)
42+
x = foo(2.)
43+
print *, x
44+
!CHECK: f2(3._8)
45+
x = foo(3.d0)
46+
print *, x
47+
end

0 commit comments

Comments
 (0)