Skip to content

Commit 8d38c9d

Browse files
committed
[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.
1 parent 134c915 commit 8d38c9d

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ class DistinguishabilityHelper {
198198
SemanticsContext &context_;
199199
struct ProcedureInfo {
200200
GenericKind kind;
201-
const Symbol &symbol;
202201
const Procedure &procedure;
203202
};
204-
std::map<SourceName, std::vector<ProcedureInfo>> nameToInfo_;
203+
std::map<SourceName, std::map<const Symbol *, ProcedureInfo>>
204+
nameToSpecifics_;
205205
};
206206

207207
void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
@@ -3441,26 +3441,26 @@ evaluate::Shape SubprogramMatchHelper::FoldShape(const evaluate::Shape &shape) {
34413441
}
34423442

34433443
void DistinguishabilityHelper::Add(const Symbol &generic, GenericKind kind,
3444-
const Symbol &specific, const Procedure &procedure) {
3445-
if (!context_.HasError(specific)) {
3446-
nameToInfo_[generic.name()].emplace_back(
3447-
ProcedureInfo{kind, specific, procedure});
3444+
const Symbol &ultimateSpecific, const Procedure &procedure) {
3445+
if (!context_.HasError(ultimateSpecific)) {
3446+
nameToSpecifics_[generic.name()].emplace(
3447+
&ultimateSpecific, ProcedureInfo{kind, procedure});
34483448
}
34493449
}
34503450

34513451
void DistinguishabilityHelper::Check(const Scope &scope) {
3452-
for (const auto &[name, info] : nameToInfo_) {
3453-
auto count{info.size()};
3454-
for (std::size_t i1{0}; i1 < count - 1; ++i1) {
3455-
const auto &[kind, symbol, proc]{info[i1]};
3456-
for (std::size_t i2{i1 + 1}; i2 < count; ++i2) {
3452+
for (const auto &[name, info] : nameToSpecifics_) {
3453+
for (auto iter1{info.begin()}; iter1 != info.end(); ++iter1) {
3454+
const auto &[ultimate, procInfo]{*iter1};
3455+
const auto &[kind, proc]{procInfo};
3456+
for (auto iter2{iter1}; ++iter2 != info.end();) {
34573457
auto distinguishable{kind.IsName()
34583458
? evaluate::characteristics::Distinguishable
34593459
: evaluate::characteristics::DistinguishableOpOrAssign};
34603460
if (!distinguishable(
3461-
context_.languageFeatures(), proc, info[i2].procedure)) {
3461+
context_.languageFeatures(), proc, iter2->second.procedure)) {
34623462
SayNotDistinguishable(GetTopLevelUnitContaining(scope), name, kind,
3463-
symbol, info[i2].symbol);
3463+
*ultimate, *iter2->first);
34643464
}
34653465
}
34663466
}

flang/test/Semantics/generic07.f90

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
2-
module m
2+
module m1
33
type :: t1
44
sequence
55
real :: x
@@ -29,8 +29,28 @@ subroutine s4a(x)
2929
end
3030
end
3131

32+
module m2
33+
type t10
34+
integer n
35+
contains
36+
procedure :: f
37+
generic:: operator(+) => f
38+
end type
39+
contains
40+
elemental type(t10) function f(x,y)
41+
class(t10), intent(in) :: x, y
42+
f%n = x%n + y%n
43+
end
44+
end
45+
46+
module m3
47+
use m2, only: rt10 => t10
48+
end
49+
3250
program test
33-
use m, only: s1a, s2a, s3a, s4a
51+
use m1, only: s1a, s2a, s3a, s4a
52+
use m2, only: t10
53+
use m3, only: rt10 ! alias for t10, ensure no distinguishability error
3454
type :: t1
3555
sequence
3656
integer :: x ! distinct type
@@ -54,7 +74,7 @@ program test
5474
interface distinguishable3
5575
procedure :: s1a, s1b
5676
end interface
57-
!ERROR: Generic 'indistinguishable' may not have specific procedures 's2a' and 's2b' as their interfaces are not distinguishable
77+
!ERROR: Generic 'indistinguishable' may not have specific procedures 's2b' and 's2a' as their interfaces are not distinguishable
5878
interface indistinguishable
5979
procedure :: s2a, s2b
6080
end interface

0 commit comments

Comments
 (0)