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