@@ -33,6 +33,8 @@ using characteristics::DummyProcedure;
33
33
using characteristics::FunctionResult;
34
34
using characteristics::Procedure;
35
35
36
+ class DistinguishabilityHelper ;
37
+
36
38
class CheckHelper {
37
39
public:
38
40
explicit CheckHelper (SemanticsContext &c) : context_{c} {}
@@ -89,6 +91,8 @@ class CheckHelper {
89
91
const SourceName &, const Symbol &, const Procedure &, std::size_t );
90
92
bool CheckDefinedAssignment (const Symbol &, const Procedure &);
91
93
bool CheckDefinedAssignmentArg (const Symbol &, const DummyArgument &, int );
94
+ void CollectSpecifics (
95
+ DistinguishabilityHelper &, const Symbol &, const GenericDetails &);
92
96
void CheckSpecifics (const Symbol &, const GenericDetails &);
93
97
void CheckEquivalenceSet (const EquivalenceSet &);
94
98
void CheckEquivalenceObject (const EquivalenceObject &);
@@ -1931,10 +1935,9 @@ void CheckHelper::CheckGeneric(
1931
1935
}
1932
1936
1933
1937
// Check that the specifics of this generic are distinguishable from each other
1934
- void CheckHelper::CheckSpecifics (
1938
+ void CheckHelper::CollectSpecifics (DistinguishabilityHelper &helper,
1935
1939
const Symbol &generic, const GenericDetails &details) {
1936
1940
GenericKind kind{details.kind ()};
1937
- DistinguishabilityHelper helper{context_};
1938
1941
for (const Symbol &specific : details.specificProcs ()) {
1939
1942
if (specific.attrs ().test (Attr::ABSTRACT)) {
1940
1943
if (auto *msg{messages_.Say (generic.name (),
@@ -1989,6 +1992,23 @@ void CheckHelper::CheckSpecifics(
1989
1992
}
1990
1993
}
1991
1994
}
1995
+ if (const Scope * parent{generic.owner ().GetDerivedTypeParent ()}) {
1996
+ if (const Symbol * inherited{parent->FindComponent (generic.name ())}) {
1997
+ if (IsAccessible (*inherited, generic.owner ().parent ())) {
1998
+ if (const auto *details{inherited->detailsIf <GenericDetails>()}) {
1999
+ // Include specifics of inherited generic of the same name, too
2000
+ CollectSpecifics (helper, *inherited, *details);
2001
+ }
2002
+ }
2003
+ }
2004
+ }
2005
+ }
2006
+
2007
+ void CheckHelper::CheckSpecifics (
2008
+ const Symbol &generic, const GenericDetails &details) {
2009
+ GenericKind kind{details.kind ()};
2010
+ DistinguishabilityHelper helper{context_};
2011
+ CollectSpecifics (helper, generic, details);
1992
2012
helper.Check (generic.owner ());
1993
2013
}
1994
2014
@@ -3947,10 +3967,11 @@ evaluate::Shape SubprogramMatchHelper::FoldShape(const evaluate::Shape &shape) {
3947
3967
}
3948
3968
3949
3969
void DistinguishabilityHelper::Add (const Symbol &generic, GenericKind kind,
3950
- const Symbol &ultimateSpecific, const Procedure &procedure) {
3951
- if (!context_.HasError (ultimateSpecific)) {
3970
+ const Symbol &specific, const Procedure &procedure) {
3971
+ const Symbol &ultimate{specific.GetUltimate ()};
3972
+ if (!context_.HasError (ultimate)) {
3952
3973
nameToSpecifics_[generic.name ()].emplace (
3953
- &ultimateSpecific , ProcedureInfo{kind, procedure});
3974
+ &ultimate , ProcedureInfo{kind, procedure});
3954
3975
}
3955
3976
}
3956
3977
@@ -3965,6 +3986,18 @@ void DistinguishabilityHelper::Check(const Scope &scope) {
3965
3986
const auto &[ultimate, procInfo]{*iter1};
3966
3987
const auto &[kind, proc]{procInfo};
3967
3988
for (auto iter2{iter1}; ++iter2 != info.end ();) {
3989
+ if (&*ultimate == &*iter2->first ) {
3990
+ continue ; // ok, actually the same procedure
3991
+ } else if (const auto *binding1{
3992
+ ultimate->detailsIf <ProcBindingDetails>()}) {
3993
+ if (const auto *binding2{
3994
+ iter2->first ->detailsIf <ProcBindingDetails>()}) {
3995
+ if (&binding1->symbol ().GetUltimate () ==
3996
+ &binding2->symbol ().GetUltimate ()) {
3997
+ continue ; // ok, bindings resolve identically
3998
+ }
3999
+ }
4000
+ }
3968
4001
auto distinguishable{kind.IsName ()
3969
4002
? evaluate::characteristics::Distinguishable
3970
4003
: evaluate::characteristics::DistinguishableOpOrAssign};
0 commit comments