[flang-commits] [flang] [Flang] Interface vs explicit intrinsics priority (PR #215355)
Ali Bahrani via flang-commits
flang-commits at lists.llvm.org
Mon Aug 31 21:21:58 PDT 2026
https://github.com/mrbahrani updated https://github.com/llvm/llvm-project/pull/215355
>From a8fe3119d5c40af505f68b93e3146d53c63cb656 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu at ip-172-31-16-239.ec2.internal>
Date: Thu, 6 Aug 2026 07:46:13 +0000
Subject: [PATCH 1/7] update ResolveGeneric to prioritize interface over
explicit intrinsic
---
flang/lib/Semantics/expression.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index fc57cc43e981c..6bf1bda749745 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3204,7 +3204,7 @@ auto ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
const Symbol *elemental{nullptr}; // matching elemental specific proc
const Symbol *nonElemental{nullptr}; // matching non-elemental specific
const auto *genericDetails{ultimate.detailsIf<semantics::GenericDetails>()};
- if (genericDetails && !explicitIntrinsic) {
+ if (genericDetails) {
std::optional<CudaMatchingDistance> crtMatchingDistance;
for (const Symbol &specific0 : genericDetails->specificProcs()) {
const Symbol &specific1{BypassGeneric(specific0)};
@@ -3276,12 +3276,12 @@ auto ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
// Return the right resolution, if there is one. Explicit intrinsics
// are preferred, then non-elements specifics, then elementals, and
// lastly structure constructors.
- if (explicitIntrinsic) {
- return {explicitIntrinsic, false};
- } else if (nonElemental) {
+ if (nonElemental) {
return {&AccessSpecific(symbol, *nonElemental), false};
} else if (elemental) {
return {&AccessSpecific(symbol, *elemental), false};
+ } else if (explicitIntrinsic) {
+ return {explicitIntrinsic, false};
}
// Check parent derived type
if (const auto *parentScope{symbol.owner().GetDerivedTypeParent()}) {
>From 4cbb115804629a2c0dc464035d64ca7b6e27084c Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu at ip-172-31-16-239.ec2.internal>
Date: Mon, 10 Aug 2026 17:19:56 +0000
Subject: [PATCH 2/7] add first explicit intrinc or interface resolution
Semantic test
In this test, sin function\'s definition is overridden by an internal interface for type Real4. As the results demonstrate, by calling sin function with R4 argument, the function is resolved into internal_definition_sin_real4
---
flang/test/Semantics/symbol34.f90 | 35 +++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 flang/test/Semantics/symbol34.f90
diff --git a/flang/test/Semantics/symbol34.f90 b/flang/test/Semantics/symbol34.f90
new file mode 100644
index 0000000000000..0f4fb57e29b61
--- /dev/null
+++ b/flang/test/Semantics/symbol34.f90
@@ -0,0 +1,35 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+!DEF: /mod Module
+module mod
+contains
+ !DEF: /mod/internal_definition_sin_real4 PUBLIC (Function) Subprogram REAL(4)
+ !DEF: /mod/internal_definition_sin_real4/r4 ObjectEntity REAL(4)
+ function internal_definition_sin_real4(r4)
+ !REF: /mod/internal_definition_sin_real4/r4
+ real r4
+ !DEF: /mod/internal_definition_sin_real4/internal_definition_sin_real4 ObjectEntity REAL(4)
+ real internal_definition_sin_real4
+ !REF: /mod/internal_definition_sin_real4/internal_definition_sin_real4
+ !REF: /mod/internal_definition_sin_real4/r4
+ internal_definition_sin_real4 = r4+100
+ end function
+end module
+!DEF: /MAIN MainProgram
+program MAIN
+ !REF: /mod
+ use :: mod
+ !DEF: /MAIN/sin ELEMENTAL, INTRINSIC, PURE (Function) Generic
+ intrinsic :: sin
+ !REF: /MAIN/sin
+ interface sin
+ !DEF: /MAIN/internal_definition_sin_real4 (Function) Use REAL(4)
+ procedure :: internal_definition_sin_real4
+ end interface
+ !DEF: /MAIN/a ObjectEntity REAL(4)
+ real a
+ !REF: /MAIN/a
+ !REF: /MAIN/internal_definition_sin_real4
+ a = sin(1.0)
+ !REF: /MAIN/a
+ print *, a
+end program
>From 465f6910f6cc01c4a67859ac0c129a52f4afc33b Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu at ip-172-31-16-239.ec2.internal>
Date: Mon, 10 Aug 2026 17:25:00 +0000
Subject: [PATCH 3/7] add real8 instance to use explicit intrinsic in presense
of interface for real4 type
---
flang/test/Semantics/symbol34.f90 | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/flang/test/Semantics/symbol34.f90 b/flang/test/Semantics/symbol34.f90
index 0f4fb57e29b61..7ba122a5b74c9 100644
--- a/flang/test/Semantics/symbol34.f90
+++ b/flang/test/Semantics/symbol34.f90
@@ -27,9 +27,14 @@ program MAIN
end interface
!DEF: /MAIN/a ObjectEntity REAL(4)
real a
+ !DEF: /MAIN/b ObjectEntity REAL(8)
+ real(kind=8) b
!REF: /MAIN/a
!REF: /MAIN/internal_definition_sin_real4
a = sin(1.0)
!REF: /MAIN/a
print *, a
+ !REF: /MAIN/b
+ !REF: /MAIN/sin
+ b = sin(1.0_8)
end program
>From 9d1dbdfc1ff31ab37ac91580fb87e8eb4cd9ce33 Mon Sep 17 00:00:00 2001
From: abahrani <ali.bahrani94521036 at gmail.com>
Date: Tue, 11 Aug 2026 12:17:19 -0400
Subject: [PATCH 4/7] update GenericResolve's if block comments to match the
real priority implemented for resolving names' \b
---
flang/lib/Semantics/expression.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 6bf1bda749745..54371f1ad7905 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3273,9 +3273,9 @@ auto ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
}
}
- // Return the right resolution, if there is one. Explicit intrinsics
- // are preferred, then non-elements specifics, then elementals, and
- // lastly structure constructors.
+ // Return the right resolution, if there is one. Non Elemental specifics
+ // are preferred, then elementals, then explicit intrinsics, and lastly
+ // structure constructors.
if (nonElemental) {
return {&AccessSpecific(symbol, *nonElemental), false};
} else if (elemental) {
>From 6108983f113f81fc08157f17887f7c2a26195f2d Mon Sep 17 00:00:00 2001
From: abahrani <ali.bahrani94521036 at gmail.com>
Date: Wed, 12 Aug 2026 10:59:39 -0400
Subject: [PATCH 5/7] fix formatting problem in
flang/lib/Semantics/expression.cpp
---
flang/lib/Semantics/expression.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 54371f1ad7905..55ee7e8a39ec9 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3274,7 +3274,7 @@ auto ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
}
// Return the right resolution, if there is one. Non Elemental specifics
- // are preferred, then elementals, then explicit intrinsics, and lastly
+ // are preferred, then elementals, then explicit intrinsics, and lastly
// structure constructors.
if (nonElemental) {
return {&AccessSpecific(symbol, *nonElemental), false};
>From 12fcc630232ee6ac8aaf2533c0da9e24443b87ee Mon Sep 17 00:00:00 2001
From: Ali Bahrani <ali.bahrani94521036 at gmail.com>
Date: Mon, 17 Aug 2026 01:13:08 -0400
Subject: [PATCH 6/7] Update flang/lib/Semantics/expression.cpp
Co-authored-by: Yusuke MINATO <minato.yusuke at fujitsu.com>
---
flang/lib/Semantics/expression.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 55ee7e8a39ec9..d7fa1197d5275 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3273,7 +3273,7 @@ auto ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
}
}
- // Return the right resolution, if there is one. Non Elemental specifics
+ // Return the right resolution, if there is one. Non-elemental specifics
// are preferred, then elementals, then explicit intrinsics, and lastly
// structure constructors.
if (nonElemental) {
>From b61b5a1b4101c72f70b8640a35a01d31ab59d1fd Mon Sep 17 00:00:00 2001
From: abahrani <ali.bahrani94521036 at gmail.com>
Date: Sun, 23 Aug 2026 02:08:13 -0400
Subject: [PATCH 7/7] extend testcases in symbol34.f90
---
flang/test/Semantics/symbol34.f90 | 152 +++++++++++++++++++++++++-----
1 file changed, 131 insertions(+), 21 deletions(-)
diff --git a/flang/test/Semantics/symbol34.f90 b/flang/test/Semantics/symbol34.f90
index 7ba122a5b74c9..e2e175e3bd5e1 100644
--- a/flang/test/Semantics/symbol34.f90
+++ b/flang/test/Semantics/symbol34.f90
@@ -14,27 +14,137 @@ function internal_definition_sin_real4(r4)
internal_definition_sin_real4 = r4+100
end function
end module
-!DEF: /MAIN MainProgram
-program MAIN
- !REF: /mod
- use :: mod
- !DEF: /MAIN/sin ELEMENTAL, INTRINSIC, PURE (Function) Generic
+
+!DEF: /mod1 Module
+module mod1
+contains
+ !DEF: /mod1/nonelemental_function_beats_intrinsic PUBLIC (Subroutine) Subprogram
+ subroutine nonelemental_function_beats_intrinsic
+ !REF: /mod
+ use :: mod
+ !DEF: /mod1/nonelemental_function_beats_intrinsic/sin ELEMENTAL, INTRINSIC, PURE (Function) Generic
+ intrinsic :: sin
+ !REF: /mod1/nonelemental_function_beats_intrinsic/sin
+ interface sin
+ !DEF: /mod1/nonelemental_function_beats_intrinsic/internal_definition_sin_real4 (Function) Use REAL(4)
+ procedure :: internal_definition_sin_real4
+ end interface
+ !DEF: /mod1/nonelemental_function_beats_intrinsic/a ObjectEntity REAL(4)
+ real a
+ !DEF: /mod1/nonelemental_function_beats_intrinsic/b ObjectEntity REAL(8)
+ real(kind=8) b
+ !REF: /mod1/nonelemental_function_beats_intrinsic/a
+ !REF: /mod1/nonelemental_function_beats_intrinsic/internal_definition_sin_real4
+ a = sin(1.0)
+ !REF: /mod1/nonelemental_function_beats_intrinsic/a
+ print *, a
+ !REF: /mod1/nonelemental_function_beats_intrinsic/b
+ !REF: /mod1/nonelemental_function_beats_intrinsic/sin
+ b = sin(1.0_8)
+ end subroutine
+end module
+
+!DEF: /mod2 Module
+module mod2
+contains
+ !DEF: /mod2/elemental_specific_sin_real4 ELEMENTAL, PUBLIC (Function) Subprogram REAL(4)
+ !DEF: /mod2/elemental_specific_sin_real4/x INTENT(IN) ObjectEntity REAL(4)
+ elemental real function elemental_specific_sin_real4(x)
+ !REF: /mod2/elemental_specific_sin_real4/x
+ real, intent(in) :: x
+ !DEF: /mod2/elemental_specific_sin_real4/elemental_specific_sin_real4 ObjectEntity REAL(4)
+ !REF: /mod2/elemental_specific_sin_real4/x
+ elemental_specific_sin_real4 = x + 100.
+ end function
+ !DEF: /mod2/elemental_specific_beats_intrinsic PUBLIC (Subroutine) Subprogram
+ subroutine elemental_specific_beats_intrinsic
+ !DEF: /mod2/elemental_specific_beats_intrinsic/sin ELEMENTAL, INTRINSIC, PURE (Function) Generic
+ intrinsic :: sin
+ !REF: /mod2/elemental_specific_beats_intrinsic/sin
+ interface sin
+ !REF: /mod2/elemental_specific_sin_real4
+ procedure :: elemental_specific_sin_real4
+ end interface
+ !DEF: /mod2/elemental_specific_beats_intrinsic/a ObjectEntity REAL(4)
+ real a
+ !REF: /mod2/elemental_specific_beats_intrinsic/a
+ !REF: /mod2/elemental_specific_sin_real4
+ a = sin(1.0)
+ !REF: /mod2/elemental_specific_beats_intrinsic/a
+ print *, a
+ end subroutine
+end module
+
+!DEF: /mod3 Module
+module mod3
+contains
+ !DEF: /mod3/subroutine_specific_cpu_time PUBLIC (Subroutine) Subprogram
+ !DEF: /mod3/subroutine_specific_cpu_time/x INTENT(OUT) ObjectEntity REAL(4)
+ subroutine subroutine_specific_cpu_time(x)
+ !REF: /mod3/subroutine_specific_cpu_time/x
+ real, intent(out) :: x
+ !REF: /mod3/subroutine_specific_cpu_time/x
+ x = 100.
+ end subroutine
+ !DEF: /mod3/subroutine_generic_beats_intrinsic PUBLIC (Subroutine) Subprogram
+ subroutine subroutine_generic_beats_intrinsic
+ !DEF: /mod3/subroutine_generic_beats_intrinsic/cpu_time INTRINSIC (Subroutine) Generic
+ intrinsic :: cpu_time
+ !REF: /mod3/subroutine_generic_beats_intrinsic/cpu_time
+ interface cpu_time
+ !REF: /mod3/subroutine_specific_cpu_time
+ procedure :: subroutine_specific_cpu_time
+ end interface
+ !DEF: /mod3/subroutine_generic_beats_intrinsic/t ObjectEntity REAL(4)
+ real t
+ !REF: /mod3/subroutine_specific_cpu_time
+ !REF: /mod3/subroutine_generic_beats_intrinsic/t
+ call cpu_time(t)
+ !REF: /mod3/subroutine_generic_beats_intrinsic/t
+ print *, t
+ end subroutine
+end module
+
+!DEF: /m Module
+module m
+ !DEF: /m/sin ELEMENTAL, INTRINSIC, PUBLIC, PURE (Function) Generic
intrinsic :: sin
- !REF: /MAIN/sin
+ !REF: /m/sin
interface sin
- !DEF: /MAIN/internal_definition_sin_real4 (Function) Use REAL(4)
- procedure :: internal_definition_sin_real4
+ !DEF: /m/fr4 PUBLIC (Function) Subprogram REAL(4)
+ procedure :: fr4
end interface
- !DEF: /MAIN/a ObjectEntity REAL(4)
- real a
- !DEF: /MAIN/b ObjectEntity REAL(8)
- real(kind=8) b
- !REF: /MAIN/a
- !REF: /MAIN/internal_definition_sin_real4
- a = sin(1.0)
- !REF: /MAIN/a
- print *, a
- !REF: /MAIN/b
- !REF: /MAIN/sin
- b = sin(1.0_8)
-end program
+contains
+ !REF: /m/fr4
+ !DEF: /m/fr4/r4 ObjectEntity REAL(4)
+ function fr4(r4)
+ !REF: /m/fr4/r4
+ real r4
+ !DEF: /m/fr4/fr4 (Implicit) ObjectEntity REAL(4)
+ !REF: /m/fr4/r4
+ fr4 = r4 + 100
+ end function
+end module
+!DEF: /mod4 Module
+module mod4
+contains
+ !DEF: /mod4/use_associated_generic_and_intrinsic PUBLIC (Subroutine) Subprogram
+ subroutine use_associated_generic_and_intrinsic
+ !REF: /m
+ use :: m
+ !DEF: /mod4/use_associated_generic_and_intrinsic/a ObjectEntity REAL(4)
+ real a
+ !DEF: /mod4/use_associated_generic_and_intrinsic/b ObjectEntity REAL(8)
+ real(kind=8) b
+ !REF: /mod4/use_associated_generic_and_intrinsic/a
+ !REF: /m/fr4
+ a = sin(0.1)
+ !REF: /mod4/use_associated_generic_and_intrinsic/a
+ print *, a
+ !REF: /mod4/use_associated_generic_and_intrinsic/b
+ !REF: /m/sin
+ b = sin(0.1_8)
+ !REF: /mod4/use_associated_generic_and_intrinsic/b
+ print *, b
+ end subroutine
+end module
More information about the flang-commits
mailing list