Skip to content

[flang] Fix bogus error on aliased derived type #69959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
26 changes: 23 additions & 3 deletions flang/test/Semantics/generic07.f90
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
module m
module m1
type :: t1
sequence
real :: x
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down