[flang-commits] [flang] [flang] Fix bogus error on aliased derived type (PR #69959)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Oct 23 11:44:47 PDT 2023


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/69959

When a derived type definition is visible by two or more names in the same scope due to USE renaming, any generic ASSIGNMENT(=) or OPERATOR() bindings in the type will produce incorrect error messages about indistinguishable specific procedures.  This is due to the use of a std::vector<> to hold a sequence of symbols and some derived information for the specific procedures of the generic name.  Change to a std::map<> indexed by the ultimate symbol of each specific so that duplicates cannot arise.

>From f2109d21c05f0c68da1fe3fa930911f14b10d0c3 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 23 Oct 2023 11:39:48 -0700
Subject: [PATCH] [flang] Fix bogus error on aliased derived type

When a derived type definition is visible by two or more names in the same
scope due to USE renaming, any generic ASSIGNMENT(=) or OPERATOR()
bindings in the type will produce incorrect error messages about
indistinguishable specific procedures.  This is due to the use of
a std::vector<> to hold a sequence of symbols and some derived information
for the specific procedures of the generic name.  Change to a std::map<>
indexed by the ultimate symbol of each specific so that duplicates
cannot arise.
---
 flang/lib/Semantics/check-declarations.cpp | 26 +++++++++++-----------
 flang/test/Semantics/generic07.f90         | 26 +++++++++++++++++++---
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 2c2866d590ae5a4..45fd9dc28fe560c 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -198,10 +198,10 @@ class DistinguishabilityHelper {
   SemanticsContext &context_;
   struct ProcedureInfo {
     GenericKind kind;
-    const Symbol &symbol;
     const Procedure &procedure;
   };
-  std::map<SourceName, std::vector<ProcedureInfo>> nameToInfo_;
+  std::map<SourceName, std::map<const Symbol *, ProcedureInfo>>
+      nameToSpecifics_;
 };
 
 void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
@@ -3441,26 +3441,26 @@ evaluate::Shape SubprogramMatchHelper::FoldShape(const evaluate::Shape &shape) {
 }
 
 void DistinguishabilityHelper::Add(const Symbol &generic, GenericKind kind,
-    const Symbol &specific, const Procedure &procedure) {
-  if (!context_.HasError(specific)) {
-    nameToInfo_[generic.name()].emplace_back(
-        ProcedureInfo{kind, specific, procedure});
+    const Symbol &ultimateSpecific, const Procedure &procedure) {
+  if (!context_.HasError(ultimateSpecific)) {
+    nameToSpecifics_[generic.name()].emplace(
+        &ultimateSpecific, ProcedureInfo{kind, procedure});
   }
 }
 
 void DistinguishabilityHelper::Check(const Scope &scope) {
-  for (const auto &[name, info] : nameToInfo_) {
-    auto count{info.size()};
-    for (std::size_t i1{0}; i1 < count - 1; ++i1) {
-      const auto &[kind, symbol, proc]{info[i1]};
-      for (std::size_t i2{i1 + 1}; i2 < count; ++i2) {
+  for (const auto &[name, info] : nameToSpecifics_) {
+    for (auto iter1{info.begin()}; iter1 != info.end(); ++iter1) {
+      const auto &[ultimate, procInfo]{*iter1};
+      const auto &[kind, proc]{procInfo};
+      for (auto iter2{iter1}; ++iter2 != info.end();) {
         auto distinguishable{kind.IsName()
                 ? evaluate::characteristics::Distinguishable
                 : evaluate::characteristics::DistinguishableOpOrAssign};
         if (!distinguishable(
-                context_.languageFeatures(), proc, info[i2].procedure)) {
+                context_.languageFeatures(), proc, iter2->second.procedure)) {
           SayNotDistinguishable(GetTopLevelUnitContaining(scope), name, kind,
-              symbol, info[i2].symbol);
+              *ultimate, *iter2->first);
         }
       }
     }
diff --git a/flang/test/Semantics/generic07.f90 b/flang/test/Semantics/generic07.f90
index 885697e4b5a9783..e7486c02a7d2ba1 100644
--- a/flang/test/Semantics/generic07.f90
+++ b/flang/test/Semantics/generic07.f90
@@ -1,5 +1,5 @@
 ! RUN: %python %S/test_errors.py %s %flang_fc1
-module m
+module m1
   type :: t1
     sequence
     real :: x
@@ -29,8 +29,28 @@ subroutine s4a(x)
   end
 end
 
+module m2
+  type t10
+    integer n
+   contains
+    procedure :: f
+    generic:: operator(+) => f
+  end type
+ contains
+  elemental type(t10) function f(x,y)
+    class(t10), intent(in) :: x, y
+    f%n = x%n + y%n
+  end
+end
+
+module m3
+  use m2, only: rt10 => t10
+end
+
 program test
-  use m, only: s1a, s2a, s3a, s4a
+  use m1, only: s1a, s2a, s3a, s4a
+  use m2, only: t10
+  use m3, only: rt10 ! alias for t10, ensure no distinguishability error
   type :: t1
     sequence
     integer :: x ! distinct type
@@ -54,7 +74,7 @@ program test
   interface distinguishable3
     procedure :: s1a, s1b
   end interface
-  !ERROR: Generic 'indistinguishable' may not have specific procedures 's2a' and 's2b' as their interfaces are not distinguishable
+  !ERROR: Generic 'indistinguishable' may not have specific procedures 's2b' and 's2a' as their interfaces are not distinguishable
   interface indistinguishable
     procedure :: s2a, s2b
   end interface



More information about the flang-commits mailing list