[flang-commits] [flang] 9ff5e12 - [Flang][Semantics] Treat host/use-associated objects as externally visible. (#192892)

via flang-commits flang-commits at lists.llvm.org
Mon May 11 05:34:19 PDT 2026


Author: ShashwathiNavada
Date: 2026-05-11T18:04:14+05:30
New Revision: 9ff5e1243da181f49617c2d5cecc3b978e06fae3

URL: https://github.com/llvm/llvm-project/commit/9ff5e1243da181f49617c2d5cecc3b978e06fae3
DIFF: https://github.com/llvm/llvm-project/commit/9ff5e1243da181f49617c2d5cecc3b978e06fae3.diff

LOG: [Flang][Semantics] Treat host/use-associated objects as externally visible. (#192892)

This patch fixes a false semantic error in Flang where function result
variables were incorrectly treated as externally visible in
pure-definability checks.

As a result, valid code assigning a pointer component of a function
result (as in flang/test/Semantics/pure-function-result-pointer.f90) was
rejected with “not definable in a pure subprogram.”

The fix updates _FindExternallyVisibleObject_ to treat function result
symbols as local, which matches Fortran semantics for function result
variables.

Added: 
    flang/test/Semantics/pure-function-result-pointer.f90
    flang/test/Semantics/pure-host-associated-result.f90

Modified: 
    flang/lib/Semantics/tools.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index bd8002e8141b2..c1ea909f21ff1 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -331,7 +331,13 @@ 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;
     }
@@ -339,12 +345,7 @@ const Symbol *FindExternallyVisibleObject(
         IsPureProcedure(ultimate.owner()) && IsFunction(ultimate.owner())) {
       return &ultimate;
     }
-  } 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;

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..85e18156f906a
--- /dev/null
+++ b/flang/test/Semantics/pure-function-result-pointer.f90
@@ -0,0 +1,46 @@
+! 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

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