[flang-commits] [flang] [Flang][Semantics] Treat function result variables as local in pure definability checks. (PR #192892)
via flang-commits
flang-commits at lists.llvm.org
Tue May 5 23:37:49 PDT 2026
https://github.com/ShashwathiNavada updated https://github.com/llvm/llvm-project/pull/192892
>From 9453e59c29fc11a706d2c37d07a399ae7dcee5b5 Mon Sep 17 00:00:00 2001
From: ShashwathiNavada <shashwathinavada at gmail.com>
Date: Sun, 19 Apr 2026 23:20:53 -0500
Subject: [PATCH 1/5] Treat function result variables as local in pure
definability checks
---
flang/lib/Semantics/tools.cpp | 4 ++
.../pure-function-result-pointer.f90 | 53 +++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 flang/test/Semantics/pure-function-result-pointer.f90
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 68307f7504e28..d2a10930ae9dc 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -338,6 +338,10 @@ const Symbol *FindExternallyVisibleObject(
IsPureProcedure(ultimate.owner()) && IsFunction(ultimate.owner())) {
return &ultimate;
}
+ } else if (IsFunctionResult(ultimate)) {
+ // A function result variable is local to its function and not an
+ // externally visible object for C1594 checks.
+ return nullptr;
} else if (ultimate.owner().IsDerivedType()) {
return nullptr;
} else if (&GetProgramUnitContaining(ultimate) !=
diff --git a/flang/test/Semantics/pure-function-result-pointer.f90 b/flang/test/Semantics/pure-function-result-pointer.f90
new file mode 100644
index 0000000000000..fc98f50b6d8dc
--- /dev/null
+++ b/flang/test/Semantics/pure-function-result-pointer.f90
@@ -0,0 +1,53 @@
+! RUN: %flang_fc1 -fsyntax-only %s
+
+module associated_func_call
+ implicit none
+
+ private
+ public :: type_t
+ public :: test_function_i
+
+ abstract interface
+ function test_function_i() result(passes)
+ implicit none
+ logical passes
+ end function
+ end interface
+
+ type type_t
+ private
+ procedure(test_function_i), pointer, nopass :: test_function_ => null()
+ contains
+ generic :: operator(==) => equals
+ procedure, private :: equals
+ end type
+
+ interface type_t
+
+ module function construct(test_function) result(test_description)
+ implicit none
+ procedure(test_function_i), intent(in), pointer :: test_function
+ type(type_t) test_description
+ end function
+
+ end interface
+
+ interface
+
+ elemental module function equals(lhs, rhs) result(lhs_eq_rhs)
+ implicit none
+ class(type_t), intent(in) :: lhs, rhs
+ logical lhs_eq_rhs
+ end function
+
+ end interface
+
+contains
+ module procedure construct
+ test_description%test_function_ => test_function
+ end procedure
+
+ module procedure equals
+ lhs_eq_rhs = associated(lhs%test_function_, rhs%test_function_)
+ end procedure
+end module associated_func_call
>From f0307f2fb5b766ece78177234ec417700bcfd0f5 Mon Sep 17 00:00:00 2001
From: ShashwathiNavada <shashwathinavada at gmail.com>
Date: Sun, 19 Apr 2026 23:32:30 -0500
Subject: [PATCH 2/5] Simple
---
flang/lib/Semantics/tools.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index d2a10930ae9dc..b338ef6e085e8 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -347,7 +347,7 @@ const Symbol *FindExternallyVisibleObject(
} else if (&GetProgramUnitContaining(ultimate) !=
&GetProgramUnitContaining(scope)) {
return &object;
- } else if (const Symbol * block{FindCommonBlockContaining(ultimate)}) {
+ } else if (const Symbol *block{FindCommonBlockContaining(ultimate)}) {
return block;
}
return nullptr;
>From d07b249f1db418cc55ce4b20302d7f255d8e7467 Mon Sep 17 00:00:00 2001
From: ShashwathiNavada <shashwathinavada at gmail.com>
Date: Mon, 20 Apr 2026 10:03:56 +0530
Subject: [PATCH 3/5] Update tools.cpp
---
flang/lib/Semantics/tools.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 1575de7d43c8e..47cafffdce8d8 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -347,7 +347,7 @@ const Symbol *FindExternallyVisibleObject(
} else if (&GetProgramUnitContaining(ultimate) !=
&GetProgramUnitContaining(scope)) {
return &object;
- } else if (const Symbol * block{FindCommonBlockContaining(ultimate)}) {
+ } else if (const Symbol *block{FindCommonBlockContaining(ultimate)}) {
return block;
}
return nullptr;
>From 4bed3f209f032a330ee80d3f070fa5ac1a7adc59 Mon Sep 17 00:00:00 2001
From: ShashwathiNavada <shashwathinavada at gmail.com>
Date: Tue, 5 May 2026 07:54:02 -0500
Subject: [PATCH 4/5] Updated the Check
---
flang/lib/Semantics/tools.cpp | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 47cafffdce8d8..d61b376237265 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -330,7 +330,12 @@ const Symbol *FindExternallyVisibleObject(
// TODO: Storage association with any object for which this predicate holds,
// once EQUIVALENCE is supported.
const Symbol &ultimate{GetAssociationRoot(object)};
- if (IsDummy(ultimate)) {
+ if (ultimate.owner().IsDerivedType()) {
+ return nullptr;
+ } else if (!IsDummy(ultimate) && (IsUseAssociated(object, scope) ||
+ IsHostAssociatedIntoSubprogram(object, scope)) ){
+ return &object;
+ } else if (IsDummy(ultimate)) {
if (IsIntentIn(ultimate)) {
return &ultimate;
}
@@ -338,16 +343,7 @@ const Symbol *FindExternallyVisibleObject(
IsPureProcedure(ultimate.owner()) && IsFunction(ultimate.owner())) {
return &ultimate;
}
- } else if (IsFunctionResult(ultimate)) {
- // A function result variable is local to its function and not an
- // externally visible object for C1594 checks.
- return nullptr;
- } else if (ultimate.owner().IsDerivedType()) {
- return nullptr;
- } else if (&GetProgramUnitContaining(ultimate) !=
- &GetProgramUnitContaining(scope)) {
- return &object;
- } else if (const Symbol *block{FindCommonBlockContaining(ultimate)}) {
+ } else if (const Symbol *block {FindCommonBlockContaining(ultimate)}) {
return block;
}
return nullptr;
>From 855806e35a3e8aa80c0a2e33be8fa60ad836e80f Mon Sep 17 00:00:00 2001
From: ShashwathiNavada <shashwathinavada at gmail.com>
Date: Wed, 6 May 2026 01:37:30 -0500
Subject: [PATCH 5/5] Suggested changes
---
flang/lib/Semantics/tools.cpp | 7 ++++---
.../Semantics/pure-function-result-pointer.f90 | 9 +--------
.../test/Semantics/pure-host-associated-result.f90 | 14 ++++++++++++++
3 files changed, 19 insertions(+), 11 deletions(-)
create mode 100644 flang/test/Semantics/pure-host-associated-result.f90
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index d61b376237265..78f722d050e69 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -332,8 +332,9 @@ const Symbol *FindExternallyVisibleObject(
const Symbol &ultimate{GetAssociationRoot(object)};
if (ultimate.owner().IsDerivedType()) {
return nullptr;
- } else if (!IsDummy(ultimate) && (IsUseAssociated(object, scope) ||
- IsHostAssociatedIntoSubprogram(object, scope)) ){
+ } else if (!IsDummy(ultimate) &&
+ (IsUseAssociated(object, scope) ||
+ IsHostAssociatedIntoSubprogram(object, scope))) {
return &object;
} else if (IsDummy(ultimate)) {
if (IsIntentIn(ultimate)) {
@@ -343,7 +344,7 @@ const Symbol *FindExternallyVisibleObject(
IsPureProcedure(ultimate.owner()) && IsFunction(ultimate.owner())) {
return &ultimate;
}
- } else if (const Symbol *block {FindCommonBlockContaining(ultimate)}) {
+ } else if (const Symbol *block{FindCommonBlockContaining(ultimate)}) {
return block;
}
return nullptr;
diff --git a/flang/test/Semantics/pure-function-result-pointer.f90 b/flang/test/Semantics/pure-function-result-pointer.f90
index fc98f50b6d8dc..85e18156f906a 100644
--- a/flang/test/Semantics/pure-function-result-pointer.f90
+++ b/flang/test/Semantics/pure-function-result-pointer.f90
@@ -2,11 +2,9 @@
module associated_func_call
implicit none
-
private
public :: type_t
public :: test_function_i
-
abstract interface
function test_function_i() result(passes)
implicit none
@@ -23,30 +21,25 @@ function test_function_i() result(passes)
end type
interface type_t
-
module function construct(test_function) result(test_description)
implicit none
procedure(test_function_i), intent(in), pointer :: test_function
type(type_t) test_description
end function
-
end interface
interface
-
elemental module function equals(lhs, rhs) result(lhs_eq_rhs)
implicit none
class(type_t), intent(in) :: lhs, rhs
logical lhs_eq_rhs
end function
-
end interface
-
+
contains
module procedure construct
test_description%test_function_ => test_function
end procedure
-
module procedure equals
lhs_eq_rhs = associated(lhs%test_function_, rhs%test_function_)
end procedure
diff --git a/flang/test/Semantics/pure-host-associated-result.f90 b/flang/test/Semantics/pure-host-associated-result.f90
new file mode 100644
index 0000000000000..3e0d8bdc6fb48
--- /dev/null
+++ b/flang/test/Semantics/pure-host-associated-result.f90
@@ -0,0 +1,14 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+
+function test_func(x) result(i)
+ integer, pointer :: i
+ real :: x
+ x = func()
+contains
+ pure real function func()
+ !ERROR: Left-hand side of assignment is not definable
+ !BECAUSE: 'i' is externally visible via 'i' and not definable in a pure subprogram
+ i = 0
+ func = 0.
+ end function
+end function
More information about the flang-commits
mailing list