@@ -161,8 +161,8 @@ class CheckHelper {
161161 void CheckDioDummyIsDefaultInteger (const Symbol &, const Symbol &);
162162 void CheckDioDummyIsScalar (const Symbol &, const Symbol &);
163163 void CheckDioDummyAttrs (const Symbol &, const Symbol &, Attr);
164- void CheckDioDtvArg (
165- const Symbol &, const Symbol *, common::DefinedIo, const Symbol &);
164+ void CheckDioDtvArg (const Symbol &proc, const Symbol &subp, const Symbol *arg,
165+ common::DefinedIo, const Symbol &generic );
166166 void CheckGenericVsIntrinsic (const Symbol &, const GenericDetails &);
167167 void CheckDefaultIntegerArg (const Symbol &, const Symbol *, Attr);
168168 void CheckDioAssumedLenCharacterArg (
@@ -3338,11 +3338,17 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
33383338 if (const Scope * dtScope{derivedType.scope ()}) {
33393339 if (auto iter{dtScope->find (generic.name ())}; iter != dtScope->end ()) {
33403340 for (auto specRef : iter->second ->get <GenericDetails>().specificProcs ()) {
3341- const Symbol & specific{specRef->get <ProcBindingDetails>().symbol ()};
3342- if (specific == proc) { // unambiguous, accept
3343- continue ;
3341+ const Symbol * specific{& specRef->get <ProcBindingDetails>().symbol ()};
3342+ if (specific == & proc) {
3343+ continue ; // unambiguous, accept
33443344 }
3345- if (const auto *specDT{GetDtvArgDerivedType (specific)};
3345+ if (const auto *peDetails{specific->detailsIf <ProcEntityDetails>()}) {
3346+ specific = peDetails->procInterface ();
3347+ if (!specific) {
3348+ continue ;
3349+ }
3350+ }
3351+ if (const auto *specDT{GetDtvArgDerivedType (*specific)};
33463352 specDT && evaluate::AreSameDerivedType (derivedType, *specDT)) {
33473353 SayWithDeclaration (*specRef, proc.name (),
33483354 " Derived type '%s' has conflicting type-bound input/output procedure '%s'" _err_en_US,
@@ -3354,11 +3360,11 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
33543360 }
33553361}
33563362
3357- void CheckHelper::CheckDioDummyIsDerived (const Symbol &subp , const Symbol &arg,
3363+ void CheckHelper::CheckDioDummyIsDerived (const Symbol &proc , const Symbol &arg,
33583364 common::DefinedIo ioKind, const Symbol &generic) {
33593365 if (const DeclTypeSpec *type{arg.GetType ()}) {
33603366 if (const DerivedTypeSpec *derivedType{type->AsDerived ()}) {
3361- CheckAlreadySeenDefinedIo (*derivedType, ioKind, subp , generic);
3367+ CheckAlreadySeenDefinedIo (*derivedType, ioKind, proc , generic);
33623368 bool isPolymorphic{type->IsPolymorphic ()};
33633369 if (isPolymorphic != IsExtensibleType (derivedType)) {
33643370 messages_.Say (arg.name (),
@@ -3399,11 +3405,11 @@ void CheckHelper::CheckDioDummyIsScalar(const Symbol &subp, const Symbol &arg) {
33993405 }
34003406}
34013407
3402- void CheckHelper::CheckDioDtvArg (const Symbol &subp , const Symbol *arg ,
3403- common::DefinedIo ioKind, const Symbol &generic) {
3408+ void CheckHelper::CheckDioDtvArg (const Symbol &proc , const Symbol &subp ,
3409+ const Symbol *arg, common::DefinedIo ioKind, const Symbol &generic) {
34043410 // Dtv argument looks like: dtv-type-spec, INTENT(INOUT) :: dtv
34053411 if (CheckDioDummyIsData (subp, arg, 0 )) {
3406- CheckDioDummyIsDerived (subp , *arg, ioKind, generic);
3412+ CheckDioDummyIsDerived (proc , *arg, ioKind, generic);
34073413 CheckDioDummyAttrs (subp, *arg,
34083414 ioKind == common::DefinedIo::ReadFormatted ||
34093415 ioKind == common::DefinedIo::ReadUnformatted
@@ -3535,57 +3541,64 @@ void CheckHelper::CheckDefinedIoProc(const Symbol &symbol,
35353541 for (auto ref : details.specificProcs ()) {
35363542 const Symbol &ultimate{ref->GetUltimate ()};
35373543 const auto *binding{ultimate.detailsIf <ProcBindingDetails>()};
3538- const Symbol &specific{*(binding ? &binding->symbol () : &ultimate)};
35393544 if (ultimate.attrs ().test (Attr::NOPASS)) { // C774
35403545 messages_.Say (" Defined input/output procedure '%s' may not have NOPASS "
35413546 " attribute" _err_en_US,
35423547 ultimate.name ());
35433548 context_.SetError (ultimate);
35443549 }
3545- if (const auto *subpDetails{specific.detailsIf <SubprogramDetails>()}) {
3550+ const Symbol *specificProc{binding ? &binding->symbol () : &ultimate};
3551+ const Symbol *specificSubp{specificProc};
3552+ if (const auto *peDetails{specificSubp->detailsIf <ProcEntityDetails>()}) {
3553+ specificSubp = peDetails->procInterface ();
3554+ if (!specificSubp) {
3555+ continue ;
3556+ }
3557+ }
3558+ if (const auto *subpDetails{specificSubp->detailsIf <SubprogramDetails>()}) {
35463559 const std::vector<Symbol *> &dummyArgs{subpDetails->dummyArgs ()};
3547- CheckDioArgCount (specific , ioKind, dummyArgs.size ());
3560+ CheckDioArgCount (*specificSubp , ioKind, dummyArgs.size ());
35483561 int argCount{0 };
35493562 for (auto *arg : dummyArgs) {
35503563 switch (argCount++) {
35513564 case 0 :
35523565 // dtv-type-spec, INTENT(INOUT) :: dtv
3553- CheckDioDtvArg (specific , arg, ioKind, symbol);
3566+ CheckDioDtvArg (*specificProc, *specificSubp , arg, ioKind, symbol);
35543567 break ;
35553568 case 1 :
35563569 // INTEGER, INTENT(IN) :: unit
3557- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_IN);
3570+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_IN);
35583571 break ;
35593572 case 2 :
35603573 if (ioKind == common::DefinedIo::ReadFormatted ||
35613574 ioKind == common::DefinedIo::WriteFormatted) {
35623575 // CHARACTER (LEN=*), INTENT(IN) :: iotype
35633576 CheckDioAssumedLenCharacterArg (
3564- specific , arg, argCount, Attr::INTENT_IN);
3577+ *specificSubp , arg, argCount, Attr::INTENT_IN);
35653578 } else {
35663579 // INTEGER, INTENT(OUT) :: iostat
3567- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3580+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
35683581 }
35693582 break ;
35703583 case 3 :
35713584 if (ioKind == common::DefinedIo::ReadFormatted ||
35723585 ioKind == common::DefinedIo::WriteFormatted) {
35733586 // INTEGER, INTENT(IN) :: v_list(:)
3574- CheckDioVlistArg (specific , arg, argCount);
3587+ CheckDioVlistArg (*specificSubp , arg, argCount);
35753588 } else {
35763589 // CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
35773590 CheckDioAssumedLenCharacterArg (
3578- specific , arg, argCount, Attr::INTENT_INOUT);
3591+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
35793592 }
35803593 break ;
35813594 case 4 :
35823595 // INTEGER, INTENT(OUT) :: iostat
3583- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3596+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
35843597 break ;
35853598 case 5 :
35863599 // CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
35873600 CheckDioAssumedLenCharacterArg (
3588- specific , arg, argCount, Attr::INTENT_INOUT);
3601+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
35893602 break ;
35903603 default :;
35913604 }
0 commit comments