The attached patch has been tested on x86_64-*-freebsd. There were no regressions.
The patch suppresses error messages for function, subroutine, and entry statements if these appear in a submodule. The interface declared in the module must match the interface in submodule (including the BIND(C) label). Ok to commit? 2019-08-02 Steven G. Kargl <ka...@gcc.gnu.org. PR fortran/89943 * decl.c (match_attr_spec): Whitespace. (gfc_match_function_decl,gfc_match_entry,gfc_match_subroutine): Suppress BIND(C) error messages for declarations in a submodule. * symbol.c (gfc_add_is_bind_c): Ditto. 2019-08-02 Steven G. Kargl <ka...@gcc.gnu.org. PR fortran/89943 * gfortran.dg/pr89943.f90: New test. -- Steve
Index: gcc/fortran/decl.c =================================================================== --- gcc/fortran/decl.c (revision 274033) +++ gcc/fortran/decl.c (working copy) @@ -5535,7 +5535,7 @@ match_attr_spec (void) break; case DECL_IS_BIND_C: - t = gfc_add_is_bind_c(¤t_attr, NULL, &seen_at[d], 0); + t = gfc_add_is_bind_c (¤t_attr, NULL, &seen_at[d], 0); break; case DECL_VALUE: @@ -7224,7 +7224,7 @@ gfc_match_function_decl (void) /* Make sure that it isn't already declared as BIND(C). If it is, it must have been marked BIND(C) with a BIND(C) attribute and that is not allowed for procedures. */ - if (sym->attr.is_bind_c == 1) + if (sym->attr.is_bind_c == 1 && sym->attr.used_in_submodule == 0) { sym->attr.is_bind_c = 0; if (sym->old_symbol != NULL) @@ -7483,7 +7483,7 @@ gfc_match_entry (void) /* Make sure that it isn't already declared as BIND(C). If it is, it must have been marked BIND(C) with a BIND(C) attribute and that is not allowed for procedures. */ - if (entry->attr.is_bind_c == 1) + if (entry->attr.is_bind_c == 1 && entry->attr.used_in_submodule == 0) { entry->attr.is_bind_c = 0; if (entry->old_symbol != NULL) @@ -7690,7 +7690,7 @@ gfc_match_subroutine (void) /* Make sure that it isn't already declared as BIND(C). If it is, it must have been marked BIND(C) with a BIND(C) attribute and that is not allowed for procedures. */ - if (sym->attr.is_bind_c == 1) + if (sym->attr.is_bind_c == 1 && sym->attr.used_in_submodule == 0) { sym->attr.is_bind_c = 0; if (sym->old_symbol != NULL) Index: gcc/fortran/symbol.c =================================================================== --- gcc/fortran/symbol.c (revision 274032) +++ gcc/fortran/symbol.c (working copy) @@ -1902,7 +1902,7 @@ gfc_add_is_bind_c (symbol_attribute *attr, const char if (is_proc_lang_bind_spec == 0 && attr->flavor == FL_PROCEDURE) gfc_error_now ("BIND(C) attribute at %L can only be used for " "variables or common blocks", where); - else if (attr->is_bind_c) + else if (attr->is_bind_c && attr->used_in_submodule == 0) gfc_error_now ("Duplicate BIND attribute specified at %L", where); else attr->is_bind_c = 1; Index: gcc/testsuite/gfortran.dg/pr89943.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pr89943.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr89943.f90 (working copy) @@ -0,0 +1,28 @@ +! { dg-do compile} +! Original code submitted by Alberto Luaces <aluaces at udc dot es> +module Foo_mod + + implicit none + + interface + module subroutine runFoo4C(ndim) bind(C, name="runFoo") + use, intrinsic :: iso_c_binding + implicit none + integer(c_int32_t) , intent(in) :: ndim + end subroutine runFoo4C + end interface + + contains +end module Foo_mod + +submodule (Foo_mod) Foo_smod + +contains + + module subroutine runFoo4C(ndim) bind(C, name="runFoo") + use, intrinsic :: iso_c_binding + implicit none + integer(c_int32_t) , intent(in) :: ndim + end subroutine runFoo4C + +end submodule Foo_smod