@@ -165,8 +165,8 @@ class CheckHelper {
165
165
void CheckDioDummyIsDefaultInteger (const Symbol &, const Symbol &);
166
166
void CheckDioDummyIsScalar (const Symbol &, const Symbol &);
167
167
void CheckDioDummyAttrs (const Symbol &, const Symbol &, Attr);
168
- void CheckDioDtvArg (
169
- const Symbol &, const Symbol *, common::DefinedIo, const Symbol &);
168
+ void CheckDioDtvArg (const Symbol &proc, const Symbol &subp, const Symbol *arg,
169
+ common::DefinedIo, const Symbol &generic );
170
170
void CheckGenericVsIntrinsic (const Symbol &, const GenericDetails &);
171
171
void CheckDefaultIntegerArg (const Symbol &, const Symbol *, Attr);
172
172
void CheckDioAssumedLenCharacterArg (
@@ -3428,11 +3428,17 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
3428
3428
if (auto iter{dtScope->find (generic.name ())}; iter != dtScope->end () &&
3429
3429
IsAccessible (*iter->second , generic.owner ())) {
3430
3430
for (auto specRef : iter->second ->get <GenericDetails>().specificProcs ()) {
3431
- const Symbol & specific{specRef->get <ProcBindingDetails>().symbol ()};
3432
- if (specific == proc) {
3431
+ const Symbol * specific{& specRef->get <ProcBindingDetails>().symbol ()};
3432
+ if (specific == & proc) {
3433
3433
continue ; // unambiguous, accept
3434
3434
}
3435
- if (const auto *specDT{GetDtvArgDerivedType (specific)};
3435
+ if (const auto *peDetails{specific->detailsIf <ProcEntityDetails>()}) {
3436
+ specific = peDetails->procInterface ();
3437
+ if (!specific) {
3438
+ continue ;
3439
+ }
3440
+ }
3441
+ if (const auto *specDT{GetDtvArgDerivedType (*specific)};
3436
3442
specDT && evaluate::AreSameDerivedType (derivedType, *specDT)) {
3437
3443
SayWithDeclaration (*specRef, proc.name (),
3438
3444
" Derived type '%s' has conflicting type-bound input/output procedure '%s'" _err_en_US,
@@ -3444,11 +3450,11 @@ void CheckHelper::CheckAlreadySeenDefinedIo(const DerivedTypeSpec &derivedType,
3444
3450
}
3445
3451
}
3446
3452
3447
- void CheckHelper::CheckDioDummyIsDerived (const Symbol &subp , const Symbol &arg,
3453
+ void CheckHelper::CheckDioDummyIsDerived (const Symbol &proc , const Symbol &arg,
3448
3454
common::DefinedIo ioKind, const Symbol &generic) {
3449
3455
if (const DeclTypeSpec *type{arg.GetType ()}) {
3450
3456
if (const DerivedTypeSpec *derivedType{type->AsDerived ()}) {
3451
- CheckAlreadySeenDefinedIo (*derivedType, ioKind, subp , generic);
3457
+ CheckAlreadySeenDefinedIo (*derivedType, ioKind, proc , generic);
3452
3458
bool isPolymorphic{type->IsPolymorphic ()};
3453
3459
if (isPolymorphic != IsExtensibleType (derivedType)) {
3454
3460
messages_.Say (arg.name (),
@@ -3486,11 +3492,11 @@ void CheckHelper::CheckDioDummyIsScalar(const Symbol &subp, const Symbol &arg) {
3486
3492
}
3487
3493
}
3488
3494
3489
- void CheckHelper::CheckDioDtvArg (const Symbol &subp , const Symbol *arg ,
3490
- common::DefinedIo ioKind, const Symbol &generic) {
3495
+ void CheckHelper::CheckDioDtvArg (const Symbol &proc , const Symbol &subp ,
3496
+ const Symbol *arg, common::DefinedIo ioKind, const Symbol &generic) {
3491
3497
// Dtv argument looks like: dtv-type-spec, INTENT(INOUT) :: dtv
3492
3498
if (CheckDioDummyIsData (subp, arg, 0 )) {
3493
- CheckDioDummyIsDerived (subp , *arg, ioKind, generic);
3499
+ CheckDioDummyIsDerived (proc , *arg, ioKind, generic);
3494
3500
CheckDioDummyAttrs (subp, *arg,
3495
3501
ioKind == common::DefinedIo::ReadFormatted ||
3496
3502
ioKind == common::DefinedIo::ReadUnformatted
@@ -3617,57 +3623,64 @@ void CheckHelper::CheckDefinedIoProc(const Symbol &symbol,
3617
3623
for (auto ref : details.specificProcs ()) {
3618
3624
const Symbol &ultimate{ref->GetUltimate ()};
3619
3625
const auto *binding{ultimate.detailsIf <ProcBindingDetails>()};
3620
- const Symbol &specific{*(binding ? &binding->symbol () : &ultimate)};
3621
3626
if (ultimate.attrs ().test (Attr::NOPASS)) { // C774
3622
3627
messages_.Say (
3623
3628
" Defined input/output procedure '%s' may not have NOPASS attribute" _err_en_US,
3624
3629
ultimate.name ());
3625
3630
context_.SetError (ultimate);
3626
3631
}
3627
- if (const auto *subpDetails{specific.detailsIf <SubprogramDetails>()}) {
3632
+ const Symbol *specificProc{binding ? &binding->symbol () : &ultimate};
3633
+ const Symbol *specificSubp{specificProc};
3634
+ if (const auto *peDetails{specificSubp->detailsIf <ProcEntityDetails>()}) {
3635
+ specificSubp = peDetails->procInterface ();
3636
+ if (!specificSubp) {
3637
+ continue ;
3638
+ }
3639
+ }
3640
+ if (const auto *subpDetails{specificSubp->detailsIf <SubprogramDetails>()}) {
3628
3641
const std::vector<Symbol *> &dummyArgs{subpDetails->dummyArgs ()};
3629
- CheckDioArgCount (specific , ioKind, dummyArgs.size ());
3642
+ CheckDioArgCount (*specificSubp , ioKind, dummyArgs.size ());
3630
3643
int argCount{0 };
3631
3644
for (auto *arg : dummyArgs) {
3632
3645
switch (argCount++) {
3633
3646
case 0 :
3634
3647
// dtv-type-spec, INTENT(INOUT) :: dtv
3635
- CheckDioDtvArg (specific , arg, ioKind, symbol);
3648
+ CheckDioDtvArg (*specificProc, *specificSubp , arg, ioKind, symbol);
3636
3649
break ;
3637
3650
case 1 :
3638
3651
// INTEGER, INTENT(IN) :: unit
3639
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_IN);
3652
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_IN);
3640
3653
break ;
3641
3654
case 2 :
3642
3655
if (ioKind == common::DefinedIo::ReadFormatted ||
3643
3656
ioKind == common::DefinedIo::WriteFormatted) {
3644
3657
// CHARACTER (LEN=*), INTENT(IN) :: iotype
3645
3658
CheckDioAssumedLenCharacterArg (
3646
- specific , arg, argCount, Attr::INTENT_IN);
3659
+ *specificSubp , arg, argCount, Attr::INTENT_IN);
3647
3660
} else {
3648
3661
// INTEGER, INTENT(OUT) :: iostat
3649
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3662
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
3650
3663
}
3651
3664
break ;
3652
3665
case 3 :
3653
3666
if (ioKind == common::DefinedIo::ReadFormatted ||
3654
3667
ioKind == common::DefinedIo::WriteFormatted) {
3655
3668
// INTEGER, INTENT(IN) :: v_list(:)
3656
- CheckDioVlistArg (specific , arg, argCount);
3669
+ CheckDioVlistArg (*specificSubp , arg, argCount);
3657
3670
} else {
3658
3671
// CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
3659
3672
CheckDioAssumedLenCharacterArg (
3660
- specific , arg, argCount, Attr::INTENT_INOUT);
3673
+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
3661
3674
}
3662
3675
break ;
3663
3676
case 4 :
3664
3677
// INTEGER, INTENT(OUT) :: iostat
3665
- CheckDefaultIntegerArg (specific , arg, Attr::INTENT_OUT);
3678
+ CheckDefaultIntegerArg (*specificSubp , arg, Attr::INTENT_OUT);
3666
3679
break ;
3667
3680
case 5 :
3668
3681
// CHARACTER (LEN=*), INTENT(INOUT) :: iomsg
3669
3682
CheckDioAssumedLenCharacterArg (
3670
- specific , arg, argCount, Attr::INTENT_INOUT);
3683
+ *specificSubp , arg, argCount, Attr::INTENT_INOUT);
3671
3684
break ;
3672
3685
default :;
3673
3686
}
0 commit comments