Skip to content

Commit

Permalink
[flang] Fix crash in semantics (#106158)
Browse files Browse the repository at this point in the history
Semantics crashes when merging a USE-associated derived type with a
local generic procedure interface of the same name. (The other direction
works.)
  • Loading branch information
klausler authored Sep 4, 2024
1 parent 9a2fd97 commit 4228e28
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
9 changes: 7 additions & 2 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,7 +3131,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
combinedDerivedType = useDerivedType;
} else {
const Scope *localScope{localDerivedType->scope()};
const Scope *useScope{useDerivedType->scope()};
const Scope *useScope{useDerivedType->GetUltimate().scope()};
if (localScope && useScope && localScope->derivedTypeSpec() &&
useScope->derivedTypeSpec() &&
evaluate::AreSameDerivedType(
Expand Down Expand Up @@ -3307,7 +3307,12 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
AddGenericUse(newUseGeneric, localName, useUltimate);
newUseGeneric.AddUse(*localSymbol);
if (combinedDerivedType) {
newUseGeneric.set_derivedType(*const_cast<Symbol *>(combinedDerivedType));
if (const auto *oldDT{newUseGeneric.derivedType()}) {
CHECK(&oldDT->GetUltimate() == &combinedDerivedType->GetUltimate());
} else {
newUseGeneric.set_derivedType(
*const_cast<Symbol *>(combinedDerivedType));
}
}
if (combinedProcedure) {
newUseGeneric.set_specific(*const_cast<Symbol *>(combinedProcedure));
Expand Down
47 changes: 47 additions & 0 deletions flang/test/Semantics/generic09.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
module m1
type foo
integer n
integer :: m = 1
end type
end

module m2
use m1
interface foo
module procedure f1
end interface
contains
type(foo) function f1(a)
real, intent(in) :: a
f1%n = a
f1%m = 2
end
end

module m3
use m2
interface foo
module procedure f2
end interface
contains
type(foo) function f2(a)
double precision, intent(in) :: a
f2%n = a
f2%m = 3
end
end

program main
use m3
type(foo) x
!CHECK: foo(n=1_4,m=1_4)
x = foo(1)
print *, x
!CHECK: f1(2._4)
x = foo(2.)
print *, x
!CHECK: f2(3._8)
x = foo(3.d0)
print *, x
end

0 comments on commit 4228e28

Please sign in to comment.