Index: flang/lib/Semantics/check-call.cpp =================================================================== --- flang/lib/Semantics/check-call.cpp +++ flang/lib/Semantics/check-call.cpp @@ -404,7 +404,12 @@ bool actualIsAllocatable{ actualLastSymbol && IsAllocatable(*actualLastSymbol)}; if (dummyIsAllocatable) { - if (!actualIsAllocatable) { + if (actualLastSymbol && !evaluate::IsCoarray(*actualLastSymbol) && + !evaluate::UnwrapWholeSymbolOrComponentDataRef(actual)) { + messages.Say( + "ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring"_err_en_US, + dummyName); + } else if (!actualIsAllocatable) { messages.Say( "ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US, dummyName); @@ -472,6 +477,7 @@ "POINTER or ALLOCATABLE dummy and actual arguments must have the same declared type and kind"_err_en_US); } } + // 15.5.2.5(4) if (const auto *derived{ evaluate::GetDerivedTypeSpec(actualType.type())}) { if (!DefersSameTypeParameters( @@ -481,6 +487,12 @@ } } } + // 15.5.2.5(4) + if (dummy.type.type().HasDeferredTypeParameter() != + actualType.type().HasDeferredTypeParameter()) { + messages.Say( + "Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE"_err_en_US); + } } // 15.5.2.8 -- coarray dummy arguments Index: flang/test/Lower/allocatable-caller.f90 =================================================================== --- flang/test/Lower/allocatable-caller.f90 +++ flang/test/Lower/allocatable-caller.f90 @@ -36,14 +36,9 @@ end subroutine end interface character(:), allocatable :: x - character(10), allocatable :: x2 - ! CHECK-DAG: %[[box:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_deferred_callEx"} - ! CHECK-DAG: %[[box2:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_deferred_callEx2"} + ! CHECK: %[[box:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_deferred_callEx"} call test_char_scalar_deferred(x) ! CHECK: fir.call @_QPtest_char_scalar_deferred(%[[box]]) : (!fir.ref>>>) -> () - call test_char_scalar_deferred(x2) - ! CHECK: %[[box2cast:.*]] = fir.convert %[[box2]] : (!fir.ref>>>) -> !fir.ref>>> - ! CHECK: fir.call @_QPtest_char_scalar_deferred(%[[box2cast]]) : (!fir.ref>>>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_scalar_explicit_call( @@ -54,14 +49,9 @@ end subroutine end interface character(10), allocatable :: x - character(:), allocatable :: x2 - ! CHECK-DAG: %[[box:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_explicit_callEx"} - ! CHECK-DAG: %[[box2:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_explicit_callEx2"} + ! CHECK: %[[box:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_char_scalar_explicit_callEx"} call test_char_scalar_explicit(x) ! CHECK: fir.call @_QPtest_char_scalar_explicit(%[[box]]) : (!fir.ref>>>) -> () - call test_char_scalar_explicit(x2) - ! CHECK: %[[box2cast:.*]] = fir.convert %[[box2]] : (!fir.ref>>>) -> !fir.ref>>> - ! CHECK: fir.call @_QPtest_char_scalar_explicit(%[[box2cast]]) : (!fir.ref>>>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_array_deferred_call( @@ -72,14 +62,9 @@ end subroutine end interface character(:), allocatable :: x(:) - character(10), allocatable :: x2(:) - ! CHECK-DAG: %[[box:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_deferred_callEx"} - ! CHECK-DAG: %[[box2:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_deferred_callEx2"} + ! CHECK: %[[box:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_deferred_callEx"} call test_char_array_deferred(x) ! CHECK: fir.call @_QPtest_char_array_deferred(%[[box]]) : (!fir.ref>>>>) -> () - call test_char_array_deferred(x2) - ! CHECK: %[[box2cast:.*]] = fir.convert %[[box2]] : (!fir.ref>>>>) -> !fir.ref>>>> - ! CHECK: fir.call @_QPtest_char_array_deferred(%[[box2cast]]) : (!fir.ref>>>>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_array_explicit_call( @@ -90,12 +75,7 @@ end subroutine end interface character(10), allocatable :: x(:) - character(:), allocatable :: x2(:) - ! CHECK-DAG: %[[box:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_explicit_callEx"} - ! CHECK-DAG: %[[box2:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_explicit_callEx2"} + ! CHECK: %[[box:.*]] = fir.alloca !fir.box>>> {{{.*}}uniq_name = "_QFtest_char_array_explicit_callEx"} call test_char_array_explicit(x) ! CHECK: fir.call @_QPtest_char_array_explicit(%[[box]]) : (!fir.ref>>>>) -> () - call test_char_array_explicit(x2) - ! CHECK: %[[box2cast:.*]] = fir.convert %[[box2]] : (!fir.ref>>>>) -> !fir.ref>>>> - ! CHECK: fir.call @_QPtest_char_array_explicit(%[[box2cast]]) : (!fir.ref>>>>) -> () end subroutine Index: flang/test/Lower/pointer-args-caller.f90 =================================================================== --- flang/test/Lower/pointer-args-caller.f90 +++ flang/test/Lower/pointer-args-caller.f90 @@ -45,15 +45,6 @@ call char_array_ptr(p) end subroutine -! CHECK-LABEL: func @_QMcall_defsPtest_ptr_to_non_deferred_char_array_ptr( -! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "p"}) { -subroutine test_ptr_to_non_deferred_char_array_ptr(p) - character(:), pointer :: p(:) -! CHECK: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref>>>>) -> !fir.ref>>>> -! CHECK: fir.call @_QPnon_deferred_char_array_ptr(%[[VAL_1]]) : (!fir.ref>>>>) -> () - call non_deferred_char_array_ptr(p) -end subroutine - ! ----------------------------------------------------------------------------- ! Test passing non-POINTER actual arguments (implicit pointer assignment) ! ----------------------------------------------------------------------------- Index: flang/test/Semantics/call05.f90 =================================================================== --- flang/test/Semantics/call05.f90 +++ flang/test/Semantics/call05.f90 @@ -118,3 +118,93 @@ end subroutine end module + +module m2 + + character(len=10), allocatable :: t1, t2, t3, t4 + character(len=:), allocatable :: t5, t6, t7, t8(:) + + character(len=10), pointer :: p1 + character(len=:), pointer :: p2 + + integer, allocatable :: x(:) + + contains + + subroutine sma(a) + character(len=:), allocatable, intent(in) :: a + end + + subroutine sma2(a) + character(len=10), allocatable, intent(in) :: a + end + + subroutine smp(p) + character(len=:), pointer, intent(in) :: p + end + + subroutine smp2(p) + character(len=10), pointer, intent(in) :: p + end + + subroutine smb(b) + integer, allocatable, intent(in) :: b(:) + end + + subroutine test() + + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call sma(t1) + + call sma2(t1) ! ok + + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call smp(p1) + + call smp2(p1) ! ok + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call sma(t2(:)) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument + call sma(t3(1)) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call sma(t4(1:2)) + + call sma(t5) ! ok + + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call sma2(t5) + + call smp(p2) ! ok + + !ERROR: Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE + call smp2(p2) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call sma(t5(:)) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument + call sma(t6(1)) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call sma(t7(1:2)) + + !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call sma(t8(1)) + + !ERROR: ALLOCATABLE dummy argument 'b=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call smb(x(:)) + + !ERROR: ALLOCATABLE dummy argument 'b=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call smb(x(2)) + + !ERROR: ALLOCATABLE dummy argument 'b=' must be associated with an ALLOCATABLE actual argument and ALLOCATABLE actual argument cannot be array section or substring + call smb(x(1:2)) + + end subroutine + +end module