From caf0892eea67349d9a1e44590c3440768136fe2b Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Wed, 21 Jun 2023 17:01:57 +0100 Subject: [PATCH] Fortran: Seg fault passing string to type cptr dummy [PR108961]. 2023-06-21 Paul Thomas gcc/fortran PR fortran/108961 * trans-expr.cc (gfc_conv_procedure_call): The hidden string length must not be passed to a formal arg of type(cptr). gcc/testsuite/ PR fortran/108961 * gfortran.dg/pr108961.f90: New test. --- gcc/fortran/trans-expr.cc | 5 ++++- gcc/testsuite/gfortran.dg/pr108961.f90 | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/pr108961.f90 diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 45a984b6bdb..3c209bcde97 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -7348,11 +7348,14 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, } /* Character strings are passed as two parameters, a length and a - pointer - except for Bind(c) which only passes the pointer. + pointer - except for Bind(c) and c_ptrs which only passe the pointer. An unlimited polymorphic formal argument likewise does not need the length. */ if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c + && !(fsym && fsym->ts.type == BT_DERIVED && fsym->ts.u.derived + && fsym->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR + && fsym->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING ) && !(fsym && UNLIMITED_POLY (fsym))) vec_safe_push (stringargs, parmse.string_length); diff --git a/gcc/testsuite/gfortran.dg/pr108961.f90 b/gcc/testsuite/gfortran.dg/pr108961.f90 new file mode 100644 index 00000000000..3e6c9df48bb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr108961.f90 @@ -0,0 +1,26 @@ +! { dg-do run } +! +! Contributed by Jeffrey Hill +! +module associate_ptr + use iso_c_binding +contains + subroutine c_f_strpointer(cptr, ptr2) + type(c_ptr), target, intent(in) :: cptr + character(kind=c_char,len=4), pointer :: ptr1 + character(kind=c_char,len=:), pointer, intent(out) :: ptr2 + call c_f_pointer(cptr, ptr1) + if (ptr1 .ne. 'abcd') stop 1 + ptr2 => ptr1 ! Failed here + end subroutine +end module + +program test_associate_ptr + use associate_ptr + character(kind=c_char, len=1), target :: char_array(7) + character(kind=c_char,len=:), pointer :: ptr2 + char_array = ['a', 'b', 'c', 'd', c_null_char, 'e', 'f'] +! The first argument was providing a constant hidden string length => segfault + call c_f_strpointer(c_loc(char_array), ptr2) + if (ptr2 .ne. 'abcd') stop 2 +end program