[flang-commits] [flang] ecf264d - [flang] Fix spurious error message due to inaccessible generic binding (#122810)

via flang-commits flang-commits at lists.llvm.org
Tue Jan 14 13:02:24 PST 2025


Author: Peter Klausler
Date: 2025-01-14T13:02:21-08:00
New Revision: ecf264d3b4eebcfcc3bd89ceac090b82fd5e75c7

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

LOG: [flang] Fix spurious error message due to inaccessible generic binding (#122810)

Generic operator/assignment checks for distinguishable specific
procedures must ignore inaccessible generic bindings.

Fixes https://github.com/llvm/llvm-project/issues/122764.

Added: 
    flang/test/Semantics/generic12.f90

Modified: 
    flang/include/flang/Semantics/tools.h
    flang/lib/Semantics/check-declarations.cpp
    flang/lib/Semantics/tools.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 1abe6cbffcf2eb..07103f98ff0412 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -241,6 +241,8 @@ inline bool NeedCUDAAlloc(const Symbol &sym) {
 const Scope *FindCUDADeviceContext(const Scope *);
 std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *);
 
+bool IsAccessible(const Symbol &, const Scope &);
+
 // Return an error if a symbol is not accessible from a scope
 std::optional<parser::MessageFormattedText> CheckAccessibleSymbol(
     const Scope &, const Symbol &);

diff  --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 99c6e16c4260f1..a7e6cf32e85eea 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -2742,6 +2742,9 @@ void CheckHelper::CheckBlockData(const Scope &scope) {
 void CheckHelper::CheckGenericOps(const Scope &scope) {
   DistinguishabilityHelper helper{context_};
   auto addSpecifics{[&](const Symbol &generic) {
+    if (!IsAccessible(generic, scope)) {
+      return;
+    }
     const auto *details{generic.GetUltimate().detailsIf<GenericDetails>()};
     if (!details) {
       // Not a generic; ensure characteristics are defined if a function.

diff  --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 3832876aca7525..052d71be434720 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -550,9 +550,7 @@ const Symbol *FindOverriddenBinding(
           if (const Symbol *
               overridden{parentScope->FindComponent(symbol.name())}) {
             // 7.5.7.3 p1: only accessible bindings are overridden
-            if (!overridden->attrs().test(Attr::PRIVATE) ||
-                FindModuleContaining(overridden->owner()) ==
-                    FindModuleContaining(symbol.owner())) {
+            if (IsAccessible(*overridden, symbol.owner())) {
               return overridden;
             } else if (overridden->attrs().test(Attr::DEFERRED)) {
               isInaccessibleDeferred = true;
@@ -1126,23 +1124,31 @@ std::optional<common::CUDADataAttr> GetCUDADataAttr(const Symbol *symbol) {
   return object ? object->cudaDataAttr() : std::nullopt;
 }
 
+bool IsAccessible(const Symbol &original, const Scope &scope) {
+  const Symbol &ultimate{original.GetUltimate()};
+  if (ultimate.attrs().test(Attr::PRIVATE)) {
+    const Scope *module{FindModuleContaining(ultimate.owner())};
+    return !module || module->Contains(scope);
+  } else {
+    return true;
+  }
+}
+
 std::optional<parser::MessageFormattedText> CheckAccessibleSymbol(
     const Scope &scope, const Symbol &symbol) {
-  if (symbol.attrs().test(Attr::PRIVATE)) {
-    if (FindModuleFileContaining(scope)) {
-      // Don't enforce component accessibility checks in module files;
-      // there may be forward-substituted named constants of derived type
-      // whose structure constructors reference private components.
-    } else if (const Scope *
-        moduleScope{FindModuleContaining(symbol.owner())}) {
-      if (!moduleScope->Contains(scope)) {
-        return parser::MessageFormattedText{
-            "PRIVATE name '%s' is only accessible within module '%s'"_err_en_US,
-            symbol.name(), moduleScope->GetName().value()};
-      }
-    }
+  if (IsAccessible(symbol, scope)) {
+    return std::nullopt;
+  } else if (FindModuleFileContaining(scope)) {
+    // Don't enforce component accessibility checks in module files;
+    // there may be forward-substituted named constants of derived type
+    // whose structure constructors reference private components.
+    return std::nullopt;
+  } else {
+    return parser::MessageFormattedText{
+        "PRIVATE name '%s' is only accessible within module '%s'"_err_en_US,
+        symbol.name(),
+        DEREF(FindModuleContaining(symbol.owner())).GetName().value()};
   }
-  return std::nullopt;
 }
 
 SymbolVector OrderParameterNames(const Symbol &typeSymbol) {

diff  --git a/flang/test/Semantics/generic12.f90 b/flang/test/Semantics/generic12.f90
new file mode 100644
index 00000000000000..1ac76c13b7a2b0
--- /dev/null
+++ b/flang/test/Semantics/generic12.f90
@@ -0,0 +1,30 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+module m
+  type t
+   contains
+    procedure :: tweedledee
+    generic :: operator(.ga.) => tweedledee
+    generic, private :: operator(.gb.) => tweedledee
+  end type
+  interface operator(.gc.)
+    module procedure tweedledum
+  end interface
+ contains
+  integer function tweedledee(x,y)
+    class(t), intent(in) :: x, y
+    tweedledee = 1
+  end
+  integer function tweedledum(x,y)
+    class(t), intent(in) :: x, y
+    tweedledum = 2
+  end
+end
+
+module badDueToAccessibility
+  !ERROR: Generic 'OPERATOR(.ga.)' may not have specific procedures 'tweedledum' and 't%tweedledee' as their interfaces are not distinguishable
+  use m, operator(.ga.) => operator(.gc.)
+end
+
+module goodDueToInaccessibility
+  use m, operator(.gb.) => operator(.gc.)
+end


        


More information about the flang-commits mailing list