Skip to content

Commit b88aced

Browse files
authored
[flang][lowering] handle procedure pointers with generic name (#108043)
Handle procedure pointer with the same name as generics in lowering to avoid crashes after #107928.
1 parent ba4bcce commit b88aced

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

flang/lib/Lower/PFTBuilder.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,14 @@ struct SymbolDependenceAnalysis {
15661566
return 0;
15671567
LLVM_DEBUG(llvm::dbgs() << "analyze symbol " << &sym << " in <"
15681568
<< &sym.owner() << ">: " << sym << '\n');
1569+
const semantics::Symbol &ultimate = sym.GetUltimate();
1570+
if (const auto *details = ultimate.detailsIf<semantics::GenericDetails>()) {
1571+
// Procedure pointers may be "hidden" behind to the generic symbol if they
1572+
// have the same name.
1573+
if (const semantics::Symbol *specific = details->specific())
1574+
analyze(*specific);
1575+
return 0;
1576+
}
15691577
const bool isProcedurePointerOrDummy =
15701578
semantics::IsProcedurePointer(sym) ||
15711579
(semantics::IsProcedure(sym) && IsDummy(sym));
@@ -1582,7 +1590,6 @@ struct SymbolDependenceAnalysis {
15821590
if (sym.owner().IsDerivedType())
15831591
return 0;
15841592

1585-
semantics::Symbol ultimate = sym.GetUltimate();
15861593
if (const auto *details =
15871594
ultimate.detailsIf<semantics::NamelistDetails>()) {
15881595
// handle namelist group symbols
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
! Test procedure pointers with the same name as generics.
2+
! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
3+
4+
module m_gen
5+
procedure(func), pointer :: foo
6+
interface foo
7+
procedure :: foo
8+
end interface
9+
interface
10+
real function func(x)
11+
real :: x
12+
end function
13+
end interface
14+
end
15+
!CHECK-LABEL: fir.global @_QMm_genEfoo : !fir.boxproc<(!fir.ref<f32>) -> f32> {
16+
!CHECK: %[[VAL_0:.*]] = fir.zero_bits (!fir.ref<f32>) -> f32
17+
!CHECK: %[[VAL_1:.*]] = fir.emboxproc %[[VAL_0]] : ((!fir.ref<f32>) -> f32) -> !fir.boxproc<(!fir.ref<f32>) -> f32>
18+
!CHECK: fir.has_value %[[VAL_1]] : !fir.boxproc<(!fir.ref<f32>) -> f32>
19+
20+
subroutine test1()
21+
use m_gen
22+
foo => func
23+
end subroutine
24+
!CHECK-LABEL: func.func @_QPtest1() {
25+
!CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMm_genEfoo) : !fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>
26+
!CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {{.*}}"_QMm_genEfoo"{{.*}} : (!fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>) -> (!fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>, !fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>)
27+
!CHECK: %[[VAL_2:.*]] = fir.address_of(@_QPfunc) : (!fir.ref<f32>) -> f32
28+
!CHECK: %[[VAL_3:.*]] = fir.emboxproc %[[VAL_2]] : ((!fir.ref<f32>) -> f32) -> !fir.boxproc<() -> ()>
29+
!CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> !fir.boxproc<(!fir.ref<f32>) -> f32>
30+
!CHECK: fir.store %[[VAL_4]] to %[[VAL_1]]#0 : !fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>
31+
32+
subroutine test_local()
33+
use m_gen, only : func
34+
procedure(func), pointer :: foo
35+
interface foo
36+
procedure :: foo
37+
end interface
38+
foo => func
39+
end subroutine
40+
!CHECK-LABEL: func.func @_QPtest_local() {
41+
!CHECK: %[[VAL_0:.*]] = fir.alloca !fir.boxproc<(!fir.ref<f32>) -> f32> {bindc_name = "foo", uniq_name = "_QFtest_localEfoo"}
42+
!CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {{.*}}"_QFtest_localEfoo"{{.*}} : (!fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>) -> (!fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>, !fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>)
43+
!CHECK: %[[VAL_4:.*]] = fir.address_of(@_QPfunc) : (!fir.ref<f32>) -> f32
44+
!CHECK: %[[VAL_5:.*]] = fir.emboxproc %[[VAL_4]] : ((!fir.ref<f32>) -> f32) -> !fir.boxproc<() -> ()>
45+
!CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.boxproc<() -> ()>) -> !fir.boxproc<(!fir.ref<f32>) -> f32>
46+
!CHECK: fir.store %[[VAL_6]] to %[[VAL_3]]#0 : !fir.ref<!fir.boxproc<(!fir.ref<f32>) -> f32>>

0 commit comments

Comments
 (0)