@@ -161,8 +161,8 @@ class CheckHelper {
161
161
void CheckDioDummyIsDefaultInteger (const Symbol &, const Symbol &);
162
162
void CheckDioDummyIsScalar (const Symbol &, const Symbol &);
163
163
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 );
166
166
void CheckGenericVsIntrinsic (const Symbol &, const GenericDetails &);
167
167
void CheckDefaultIntegerArg (const Symbol &, const Symbol *, Attr);
168
168
void CheckDioAssumedLenCharacterArg (
@@ -3338,11 +3338,17 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
3338
3338
if (const Scope * dtScope{derivedType.scope ()}) {
3339
3339
if (auto iter{dtScope->find (generic.name ())}; iter != dtScope->end ()) {
3340
3340
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
3344
3344
}
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)};
3346
3352
specDT && evaluate::AreSameDerivedType (derivedType, *specDT)) {
3347
3353
SayWithDeclaration (*specRef, proc.name (),
3348
3354
" Derived type '%s' has conflicting type-bound input/output procedure '%s'" _err_en_US,
@@ -3354,11 +3360,11 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
3354
3360
}
3355
3361
}
3356
3362
3357
- void CheckHelper::CheckDioDummyIsDerived (const Symbol &subp , const Symbol &arg,
3363
+ void CheckHelper::CheckDioDummyIsDerived (const Symbol &proc , const Symbol &arg,
3358
3364
common::DefinedIo ioKind, const Symbol &generic) {
3359
3365
if (const DeclTypeSpec *type{arg.GetType ()}) {
3360
3366
if (const DerivedTypeSpec *derivedType{type->AsDerived ()}) {
3361
- CheckAlreadySeenDefinedIo (*derivedType, ioKind, subp , generic);
3367
+ CheckAlreadySeenDefinedIo (*derivedType, ioKind, proc , generic);
3362
3368
bool isPolymorphic{type->IsPolymorphic ()};
3363
3369
if (isPolymorphic != IsExtensibleType (derivedType)) {
3364
3370
messages_.Say (arg.name (),
@@ -3399,11 +3405,11 @@ void CheckHelper::CheckDioDummyIsScalar(const Symbol &subp, const Symbol &arg) {
3399
3405
}
3400
3406
}
3401
3407
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) {
3404
3410
// Dtv argument looks like: dtv-type-spec, INTENT(INOUT) :: dtv
3405
3411
if (CheckDioDummyIsData (subp, arg, 0 )) {
3406
- CheckDioDummyIsDerived (subp , *arg, ioKind, generic);
3412
+ CheckDioDummyIsDerived (proc , *arg, ioKind, generic);
3407
3413
CheckDioDummyAttrs (subp, *arg,
3408
3414
ioKind == common::DefinedIo::ReadFormatted ||
3409
3415
ioKind == common::DefinedIo::ReadUnformatted
@@ -3535,57 +3541,64 @@ void CheckHelper::CheckDefinedIoProc(const Symbol &symbol,
3535
3541
for (auto ref : details.specificProcs ()) {
3536
3542
const Symbol &ultimate{ref->GetUltimate ()};
3537
3543
const auto *binding{ultimate.detailsIf <ProcBindingDetails>()};
3538
- const Symbol &specific{*(binding ? &binding->symbol () : &ultimate)};
3539
3544
if (ultimate.attrs ().test (Attr::NOPASS)) { // C774
3540
3545
messages_.Say (" Defined input/output procedure '%s' may not have NOPASS "
3541
3546
" attribute" _err_en_US,
3542
3547
ultimate.name ());
3543
3548
context_.SetError (ultimate);
3544
3549
}
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>()}) {
3546
3559
const std::vector<Symbol *> &dummyArgs{subpDetails->dummyArgs ()};
3547
- CheckDioArgCount (specific , ioKind, dummyArgs.size ());
3560
+ CheckDioArgCount (*specificSubp , ioKind, dummyArgs.size ());
3548
3561
int argCount{0 };
3549
3562
for (auto *arg : dummyArgs) {
3550
3563
switch (argCount++) {
3551
3564
case 0 :
3552
3565
// dtv-type-spec, INTENT(INOUT) :: dtv
3553
- CheckDioDtvArg (specific , arg, ioKind, symbol);
3566
+ CheckDioDtvArg (*specificProc, *specificSubp , arg, ioKind, symbol);
3554
3567
break ;
3555
3568
case 1 :
3556
3569
// INTEGER, INTENT(IN) :: unit
3557
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_IN);
3570
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_IN);
3558
3571
break ;
3559
3572
case 2 :
3560
3573
if (ioKind == common::DefinedIo::ReadFormatted ||
3561
3574
ioKind == common::DefinedIo::WriteFormatted) {
3562
3575
// CHARACTER (LEN=*), INTENT(IN) :: iotype
3563
3576
CheckDioAssumedLenCharacterArg (
3564
- specific , arg, argCount, Attr::INTENT_IN);
3577
+ *specificSubp , arg, argCount, Attr::INTENT_IN);
3565
3578
} else {
3566
3579
// INTEGER, INTENT(OUT) :: iostat
3567
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3580
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
3568
3581
}
3569
3582
break ;
3570
3583
case 3 :
3571
3584
if (ioKind == common::DefinedIo::ReadFormatted ||
3572
3585
ioKind == common::DefinedIo::WriteFormatted) {
3573
3586
// INTEGER, INTENT(IN) :: v_list(:)
3574
- CheckDioVlistArg (specific , arg, argCount);
3587
+ CheckDioVlistArg (*specificSubp , arg, argCount);
3575
3588
} else {
3576
3589
// CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
3577
3590
CheckDioAssumedLenCharacterArg (
3578
- specific , arg, argCount, Attr::INTENT_INOUT);
3591
+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
3579
3592
}
3580
3593
break ;
3581
3594
case 4 :
3582
3595
// INTEGER, INTENT(OUT) :: iostat
3583
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3596
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
3584
3597
break ;
3585
3598
case 5 :
3586
3599
// CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
3587
3600
CheckDioAssumedLenCharacterArg (
3588
- specific , arg, argCount, Attr::INTENT_INOUT);
3601
+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
3589
3602
break ;
3590
3603
default :;
3591
3604
}
0 commit comments