diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 2c2866d590ae5..45fd9dc28fe56 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> nameToInfo_; + std::map> + 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 885697e4b5a97..e7486c02a7d2b 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