Index: flang/docs/Extensions.md =================================================================== --- flang/docs/Extensions.md +++ flang/docs/Extensions.md @@ -250,6 +250,12 @@ * A type-bound procedure binding can be passed as an actual argument corresponding to a dummy procedure and can be used as the target of a procedure pointer assignment statement. +* An explicit `INTERFACE` can declare the interface of a + procedure pointer even if it is not a dummy argument. +* A `NOPASS` type-bound procedure binding is required by C1529 + to apply only to a scalar data-ref, but most compilers don't + enforce it and the constraint is not necessary for a correct + implementation. ### Extensions supported when enabled by options Index: flang/lib/Semantics/expression.cpp =================================================================== --- flang/lib/Semantics/expression.cpp +++ flang/lib/Semantics/expression.cpp @@ -2093,6 +2093,19 @@ if (dataRef && !CheckDataRef(*dataRef)) { return std::nullopt; } + if (dataRef && dataRef->Rank() > 0) { + if (sym->has() && + sym->attrs().test(semantics::Attr::NOPASS)) { + // C1529 seems unnecessary and most compilers don't enforce it. + AttachDeclaration( + Say(sc.component.source, + "Base of NOPASS type-bound procedure reference should be scalar"_port_en_US), + *sym); + } else if (IsProcedurePointer(*sym)) { // C919 + Say(sc.component.source, + "Base of procedure component reference must be scalar"_err_en_US); + } + } if (const Symbol *resolution{ GetBindingResolution(dtExpr->GetType(), *sym)}) { AddPassArg(arguments, std::move(*dtExpr), *sym, false); Index: flang/test/Semantics/bindings01.f90 =================================================================== --- flang/test/Semantics/bindings01.f90 +++ flang/test/Semantics/bindings01.f90 @@ -215,6 +215,24 @@ end subroutine end module m7 +module m8 ! C1529 - warning only + type t + procedure(mysubr), pointer, nopass :: pp + contains + procedure, nopass :: tbp => mysubr + end type + contains + subroutine mysubr + end subroutine + subroutine test + type(t) a(2) + !PORTABILITY: Base of NOPASS type-bound procedure reference should be scalar + call a%tbp + !ERROR: Base of procedure component reference must be scalar + call a%pp + end subroutine +end module + program test use m1 type,extends(t) :: t2