The attached patch is verging on the obvious. Thanks to Tobias for spotting Vipul's messages on the J3 list.
Regtests on FC30/x86_64 - OK for trunk and 9-branch? Paul 2019-11-03 Paul Thomas <pa...@gcc.gnu.org> PR fortran/92123 *decl.c (gfc_verify_c_interop_param): Remove error asserting that pointer or allocatable variables in a bind C procedure are not supported. Delete some trailing spaces. * trans-stmt.c (trans_associate_var): Correct the attempt to treat scalar pointer or allocatable temporaries as if they are array descriptors. 2019-11-03 Paul Thomas <pa...@gcc.gnu.org> PR fortran/92123 * gfortran.dg/bind_c_procs_3.f90 : New test. * gfortran.dg/ISO_Fortran_binding_15.c : New test. * gfortran.dg/ISO_Fortran_binding_15.f90 : Additional source.
Index: gcc/fortran/decl.c =================================================================== *** gcc/fortran/decl.c (revision 277531) --- gcc/fortran/decl.c (working copy) *************** gfc_verify_c_interop_param (gfc_symbol * *** 1560,1574 **** sym->ns->proc_name->name)) retval = false; - if ((sym->attr.allocatable || sym->attr.pointer) && !sym->as) - { - gfc_error ("Scalar variable %qs at %L with POINTER or " - "ALLOCATABLE in procedure %qs with BIND(C) is not yet" - " supported", sym->name, &(sym->declared_at), - sym->ns->proc_name->name); - retval = false; - } - if (sym->attr.optional == 1 && sym->attr.value) { gfc_error ("Variable %qs at %L cannot have both the OPTIONAL " --- 1560,1565 ---- *************** gfc_match_entry (void) *** 7547,7553 **** entry->attr.is_bind_c = 0; loc = entry->old_symbol != NULL ! ? entry->old_symbol->declared_at : gfc_current_locus; gfc_error_now ("BIND(C) attribute at %L can only be used for " "variables or common blocks", &loc); } --- 7538,7544 ---- entry->attr.is_bind_c = 0; loc = entry->old_symbol != NULL ! ? entry->old_symbol->declared_at : gfc_current_locus; gfc_error_now ("BIND(C) attribute at %L can only be used for " "variables or common blocks", &loc); } *************** gfc_match_derived_decl (void) *** 10288,10294 **** } /* In free source form, need to check for TYPE XXX as oppose to TYPEXXX. ! But, we need to simply return for TYPE(. */ if (m == MATCH_NO && gfc_current_form == FORM_FREE) { char c = gfc_peek_ascii_char (); --- 10279,10285 ---- } /* In free source form, need to check for TYPE XXX as oppose to TYPEXXX. ! But, we need to simply return for TYPE(. */ if (m == MATCH_NO && gfc_current_form == FORM_FREE) { char c = gfc_peek_ascii_char (); Index: gcc/fortran/trans-stmt.c =================================================================== *** gcc/fortran/trans-stmt.c (revision 277531) --- gcc/fortran/trans-stmt.c (working copy) *************** trans_associate_var (gfc_symbol *sym, gf *** 1841,1850 **** if (rank > 0) copy_descriptor (&se.post, se.expr, desc, rank); else ! { ! tmp = gfc_conv_descriptor_data_get (desc); ! gfc_conv_descriptor_data_set (&se.post, se.expr, tmp); ! } /* The dynamic type could have changed too. */ if (sym->ts.type == BT_CLASS) --- 1841,1847 ---- if (rank > 0) copy_descriptor (&se.post, se.expr, desc, rank); else ! gfc_conv_descriptor_data_set (&se.post, se.expr, desc); /* The dynamic type could have changed too. */ if (sym->ts.type == BT_CLASS) Index: gcc/testsuite/gfortran.dg/bind_c_procs_3.f90 =================================================================== *** gcc/testsuite/gfortran.dg/bind_c_procs_3.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/bind_c_procs_3.f90 (working copy) *************** *** 0 **** --- 1,25 ---- + ! { dg-do run } + ! + ! Test the fix for PR92123, in which 'dat' caused an error with the message + ! "Scalar variable 'dat' at ?? with POINTER or ALLOCATABLE in procedure Fsub + ! with BIND(C) is not yet supported." + ! + ! Contributed by Vipul Parekh <parek...@gmail.com> + ! + module m + use, intrinsic :: iso_c_binding, only : c_int + contains + subroutine Fsub( dat ) bind(C, name="Fsub") + !.. Argument list + integer(c_int), allocatable, intent(out) :: dat + dat = 42 + return + end subroutine + end module m + + use, intrinsic :: iso_c_binding, only : c_int + use m, only : Fsub + integer(c_int), allocatable :: x + call Fsub( x ) + if (x .ne. 42) stop 1 + end Index: gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.c =================================================================== *** gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.c (nonexistent) --- gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.c (working copy) *************** *** 0 **** --- 1,41 ---- + /* Test the fix for PR92123. */ + + /* Contributed by Vipul Parekh <parek...@gmail.com> */ + + #include <stdlib.h> + #include <stdio.h> + #include "../../../libgfortran/ISO_Fortran_binding.h" + + // Prototype for Fortran functions + extern void Fsub(CFI_cdesc_t *); + + int main() + { + CFI_CDESC_T(0) dat; + int irc = 0; + + irc = CFI_establish((CFI_cdesc_t *)&dat, NULL, + CFI_attribute_allocatable, + CFI_type_int, 0, (CFI_rank_t)0, NULL); + if (irc != CFI_SUCCESS) + { + printf("CFI_establish failed: irc = %d.\n", irc); + return EXIT_FAILURE; + } + + Fsub((CFI_cdesc_t *)&dat); + if (*(int *)dat.base_addr != 42) + { + printf("Fsub returned = %d.\n", *(int *)dat.base_addr); + return EXIT_FAILURE; + } + + irc = CFI_deallocate((CFI_cdesc_t *)&dat); + if (irc != CFI_SUCCESS) + { + printf("CFI_deallocate for dat failed: irc = %d.\n", irc); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } Index: gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.f90 =================================================================== *** gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/ISO_Fortran_binding_15.f90 (working copy) *************** *** 0 **** --- 1,20 ---- + ! { dg-do run { target c99_runtime } } + ! { dg-additional-sources ISO_Fortran_binding_15.c } + ! + ! Test the fix for PR921233. The additional source is the main program. + ! + ! Contributed by Vipul Parekh <parek...@gmail.com> + ! + module m + use, intrinsic :: iso_c_binding, only : c_int + contains + subroutine Fsub( dat ) bind(C, name="Fsub") + integer(c_int), allocatable, intent(out) :: dat(..) + select rank (dat) + rank (0) + allocate( dat ) + dat = 42 + end select + return + end subroutine + end module m