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

via flang-commits flang-commits at lists.llvm.org
Tue Oct 31 11:26:35 PDT 2023


Author: Peter Klausler
Date: 2023-10-31T11:26:30-07:00
New Revision: e87cdda35e062f39e72b5912a255821bf002041d

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

LOG: [flang] Fix bogus error on aliased derived type (#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.

Added: 
    

Modified: 
    flang/lib/Semantics/check-declarations.cpp
    flang/test/Semantics/generic07.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 87db92c6fc49362..0b847f5c3408bf9 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) {
@@ -3444,26 +3444,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