@@ -33,6 +33,8 @@ using characteristics::DummyProcedure;
3333using characteristics::FunctionResult;
3434using characteristics::Procedure;
3535
36+ class DistinguishabilityHelper ;
37+
3638class CheckHelper {
3739public:
3840 explicit CheckHelper (SemanticsContext &c) : context_{c} {}
@@ -89,6 +91,8 @@ class CheckHelper {
8991 const SourceName &, const Symbol &, const Procedure &, std::size_t );
9092 bool CheckDefinedAssignment (const Symbol &, const Procedure &);
9193 bool CheckDefinedAssignmentArg (const Symbol &, const DummyArgument &, int );
94+ void CollectSpecifics (
95+ DistinguishabilityHelper &, const Symbol &, const GenericDetails &);
9296 void CheckSpecifics (const Symbol &, const GenericDetails &);
9397 void CheckEquivalenceSet (const EquivalenceSet &);
9498 void CheckEquivalenceObject (const EquivalenceObject &);
@@ -1931,10 +1935,9 @@ void CheckHelper::CheckGeneric(
19311935}
19321936
19331937// Check that the specifics of this generic are distinguishable from each other
1934- void CheckHelper::CheckSpecifics (
1938+ void CheckHelper::CollectSpecifics (DistinguishabilityHelper &helper,
19351939 const Symbol &generic, const GenericDetails &details) {
19361940 GenericKind kind{details.kind ()};
1937- DistinguishabilityHelper helper{context_};
19381941 for (const Symbol &specific : details.specificProcs ()) {
19391942 if (specific.attrs ().test (Attr::ABSTRACT)) {
19401943 if (auto *msg{messages_.Say (generic.name (),
@@ -1989,6 +1992,23 @@ void CheckHelper::CheckSpecifics(
19891992 }
19901993 }
19911994 }
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);
19922012 helper.Check (generic.owner ());
19932013}
19942014
@@ -3947,10 +3967,11 @@ evaluate::Shape SubprogramMatchHelper::FoldShape(const evaluate::Shape &shape) {
39473967}
39483968
39493969void 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)) {
39523973 nameToSpecifics_[generic.name ()].emplace (
3953- &ultimateSpecific , ProcedureInfo{kind, procedure});
3974+ &ultimate , ProcedureInfo{kind, procedure});
39543975 }
39553976}
39563977
@@ -3965,6 +3986,18 @@ void DistinguishabilityHelper::Check(const Scope &scope) {
39653986 const auto &[ultimate, procInfo]{*iter1};
39663987 const auto &[kind, proc]{procInfo};
39673988 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+ }
39684001 auto distinguishable{kind.IsName ()
39694002 ? evaluate::characteristics::Distinguishable
39704003 : evaluate::characteristics::DistinguishableOpOrAssign};
0 commit comments