This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR fortran/89943 -- Duplicate BIND(c) allowed (?)


The attached patch allows the declaration of a BIND(C)
module function or module subroutine to appear in a
submodule (see testcases).  Regression test was clean.
OK to commit?

Before a rubber stamped 'OK'.  I do NOT use submodules.
A submodule user needs to pipe up on the validity of
the patch.


2019-10-04  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/89943
	decl.c (gfc_match_function_decl): Ignore duplicate BIND(C) for function
	declaration in submodule.
	(gfc_match_entry): Use temporary for locus, which allows removal of
	one gfc_error_now().
	(gfc_match_subroutine): Ignore duplicate BIND(C) for subroutine
	declaration in submodule.

2019-10-04  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/89943
	* gfortran.dg/pr89943_1.f90: New test.
	* gfortran.dg/pr89943_2.f90: Ditto.

-- 
Steve
Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 276601)
+++ gcc/fortran/decl.c	(working copy)
@@ -7259,13 +7259,16 @@ gfc_match_function_decl (void)
   if (sym->attr.is_bind_c == 1)
     {
       sym->attr.is_bind_c = 0;
-      if (sym->old_symbol != NULL)
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks",
-                       &(sym->old_symbol->declared_at));
-      else
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks", &gfc_current_locus);
+
+      if (gfc_state_stack->previous
+	  && gfc_state_stack->previous->state != COMP_SUBMODULE)
+	{
+	  locus loc;
+	  loc = sym->old_symbol != NULL
+	    ? sym->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);
+	}
     }
 
   if (found_match != MATCH_YES)
@@ -7517,16 +7520,16 @@ gfc_match_entry (void)
      not allowed for procedures.  */
   if (entry->attr.is_bind_c == 1)
     {
+      locus loc;
+
       entry->attr.is_bind_c = 0;
-      if (entry->old_symbol != NULL)
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks",
-                       &(entry->old_symbol->declared_at));
-      else
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks", &gfc_current_locus);
-    }
 
+      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);
+     }
+
   /* Check what next non-whitespace character is so we can tell if there
      is the required parens if we have a BIND(C).  */
   old_loc = gfc_current_locus;
@@ -7725,13 +7728,16 @@ gfc_match_subroutine (void)
   if (sym->attr.is_bind_c == 1)
     {
       sym->attr.is_bind_c = 0;
-      if (sym->old_symbol != NULL)
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks",
-                       &(sym->old_symbol->declared_at));
-      else
-        gfc_error_now ("BIND(C) attribute at %L can only be used for "
-                       "variables or common blocks", &gfc_current_locus);
+
+      if (gfc_state_stack->previous
+	  && gfc_state_stack->previous->state != COMP_SUBMODULE)
+	{
+	  locus loc;
+	  loc = sym->old_symbol != NULL
+	    ? sym->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);
+	}
     }
 
   /* C binding names are not allowed for internal procedures.  */
Index: gcc/testsuite/gfortran.dg/pr89943_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr89943_1.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr89943_1.f90	(working copy)
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! PR fortran/89943
+! Code contributed by Alberto Luaces  <aluaces at udc dot se>
+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
+
Index: gcc/testsuite/gfortran.dg/pr89943_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr89943_2.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr89943_2.f90	(working copy)
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! PR fortran/89943
+! Code contributed by Alberto Luaces  <aluaces at udc dot se>
+module Foo_mod
+
+   implicit none
+
+   interface
+      module function runFoo4C(ndim) bind(C, name="runFoo")
+         use, intrinsic :: iso_c_binding
+         implicit none
+         integer runFoo4c
+         integer(c_int32_t) , intent(in) :: ndim
+      end function runFoo4C
+   end interface
+
+   contains
+
+end module Foo_mod
+
+submodule(Foo_mod) Foo_smod
+
+   contains
+
+      module function runFoo4C(ndim) bind(C, name="runFoo")
+         use, intrinsic :: iso_c_binding
+         implicit none
+         integer runFoo4c
+         integer(c_int32_t) , intent(in) :: ndim
+      end function runFoo4C
+
+end submodule Foo_smod
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]