diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp --- a/flang/lib/Semantics/type.cpp +++ b/flang/lib/Semantics/type.cpp @@ -369,6 +369,15 @@ : evaluate::NonPointerInitializationExpr( newSymbol, std::move(*init), foldingContext()); } + } else if (auto *procDetails{newSymbol.detailsIf()}) { + // We have a procedure pointer. Instantiate its return type + if (const DeclTypeSpec * returnType{InstantiateType(newSymbol)}) { + ProcInterface &interface{procDetails->interface()}; + if (!interface.symbol()) { + // Don't change the type for interfaces based on symbols + interface.set_type(*returnType); + } + } } } diff --git a/flang/test/Semantics/resolve105.f90 b/flang/test/Semantics/resolve105.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/resolve105.f90 @@ -0,0 +1,82 @@ +! RUN: %S/test_errors.sh %s %t %f18 +! Test instantiation of components that are procedure pointers. +! +program test + type dtype(kindParam) + integer, kind :: kindParam = 4 + !ERROR: KIND parameter value (66) of intrinsic type REAL did not resolve to a supported value + !ERROR: KIND parameter value (55) of intrinsic type REAL did not resolve to a supported value + procedure (real(kindParam)), pointer, nopass :: field => null() + end type + + type base(kindParam) + integer, kind :: kindParam = 4 + !ERROR: KIND parameter value (77) of intrinsic type REAL did not resolve to a supported value + procedure (real(kindParam)), pointer, nopass :: field => null() + end type + type dependentType(kindParam) + integer, kind :: kindParam = 4 + procedure (type(base(kindParam))), pointer, nopass :: field => null() + end type + + ! OK unless entities are declared with the default type + type badDefaultType(kindParam) + integer, kind :: kindParam = 99 + !ERROR: KIND parameter value (99) of intrinsic type REAL did not resolve to a supported value + !ERROR: KIND parameter value (44) of intrinsic type REAL did not resolve to a supported value + procedure (real(kindParam)), pointer, nopass :: field => null() + end type + + type parent(kindParam) + integer, kind :: kindParam = 4 + !ERROR: KIND parameter value (33) of intrinsic type REAL did not resolve to a supported value + !ERROR: KIND parameter value (88) of intrinsic type REAL did not resolve to a supported value + procedure (real(kindParam)), pointer, nopass :: parentField => null() + end type + type, extends(parent) :: child + integer :: field + end type child +contains + subroutine testGoodDefault(arg) + type(dtype) :: arg + if (associated(arg%field)) stop 'fail' + end subroutine testGoodDefault + + subroutine testStar(arg) + type(dtype(*)),intent(inout) :: arg + if (associated(arg%field)) stop 'fail' + end subroutine testStar + + subroutine testBadDeclaration(arg) + type(dtype(66)) :: arg + if (associated(arg%field)) stop 'fail' + end subroutine testBadDeclaration + + subroutine testBadLocalDeclaration() + type(dtype(55)) :: local + if (associated(local%field)) stop 'fail' + end subroutine testBadLocalDeclaration + + subroutine testDependent() + type(dependentType(77)) :: local + end subroutine testDependent + + subroutine testBadDefault() + type(badDefaultType) :: local + end subroutine testBadDefault + + subroutine testBadDefaultWithBadDeclaration() + type(badDefaultType(44)) :: local + end subroutine testBadDefaultWithBadDeclaration + + subroutine testBadDefaultWithGoodDeclaration() + type(badDefaultType(4)) :: local + end subroutine testBadDefaultWithGoodDeclaration + + subroutine testExtended() + type(child(33)) :: local1 + type(child(4)) :: local2 + type(parent(88)) :: local3 + type(parent(8)) :: local4 + end subroutine testExtended +end program test