public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Steve Kargl <sgk@troutmask.apl.washington.edu>
To: Paul Richard Thomas <paul.richard.thomas@gmail.com>
Cc: "fortran@gcc.gnu.org" <fortran@gcc.gnu.org>,
	       gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] PR fortran/89943 -- Duplicate BIND(c) allowed (?)
Date: Mon, 14 Oct 2019 20:09:00 -0000	[thread overview]
Message-ID: <20191014200624.GA39911@troutmask.apl.washington.edu> (raw)
In-Reply-To: <CAGkQGi+kK1+sJeowv1K+uyU4zRThCztNvJH4=pdVPN-aukKhGw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 8750 bytes --]

See attached patch.  It includes my previous patch and
patch to check for C1550.  OK to commit?

2019-10-14  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.  Implement at check for F2018 C1550.
	(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.  Implement at check for F2018 C1550.

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

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



On Sat, Oct 12, 2019 at 02:57:25PM +0100, Paul Richard Thomas wrote:
> Hi Steve,
> 
> In the F2018 standard: C1550 (R1526) If MODULE appears in the prefix
> of a module subprogram and a binding label is specified, it
> shall be the same as the binding label specified in the corresponding
> module procedure interface body.
> 
> While it does not say explicitly that a repeat binding label is
> allowed, I think that the implication is clear enough.
> 
> The patch is OK as it is but it would be nice if C1550 is or would be
> implemented.
> 
> Thanks
> 
> Paul
> 
> On Fri, 11 Oct 2019 at 19:31, Steve Kargl
> <sgk@troutmask.apl.washington.edu> wrote:
> >
> > PING.
> >
> > On Fri, Oct 04, 2019 at 03:26:53PM -0700, Steve Kargl wrote:
> > > 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
> > > +
> >
> >
> > --
> > Steve
> > 20170425 https://www.youtube.com/watch?v=VWUpyCsUKR4
> > 20161221 https://www.youtube.com/watch?v=IbCHE-hONow
> 
> 
> 
> -- 
> "If you can't explain it simply, you don't understand it well enough"
> - Albert Einstein

-- 
Steve
20170425 https://www.youtube.com/watch?v=VWUpyCsUKR4
20161221 https://www.youtube.com/watch?v=IbCHE-hONow

[-- Attachment #2: pr.diff --]
[-- Type: text/x-diff, Size: 9178 bytes --]

Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 276967)
+++ gcc/fortran/decl.c	(working copy)
@@ -7263,13 +7263,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)
@@ -7283,6 +7286,24 @@ gfc_match_function_decl (void)
 	found_match = suffix_match;
     }
 
+  /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
+     subprogram and a binding label is specified, it shall be the
+     same as the binding label specified in the corresponding module
+     procedure interface body.  */
+    if (sym->attr.is_bind_c && sym->attr.module_procedure && sym->old_symbol
+  	&& strcmp (sym->name, sym->old_symbol->name) == 0
+	&& strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
+      {
+	  const char *null = "NULL", *s1, *s2;
+	  s1 = sym->binding_label;
+	  if (!s1) s1 = null;
+	  s2 = sym->old_symbol->binding_label;
+	  if (!s2) s2 = null;
+          gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
+	  sym->refs++;	/* Needed to avoid an ICE in gfc_release_symbol */
+	  return MATCH_ERROR;
+      }
+
   if(found_match != MATCH_YES)
     m = MATCH_ERROR;
   else
@@ -7521,16 +7542,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;
@@ -7729,13 +7750,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.  */
@@ -7776,6 +7800,24 @@ gfc_match_subroutine (void)
           gfc_error ("Missing required parentheses before BIND(C) at %C");
           return MATCH_ERROR;
         }
+
+      /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
+	 subprogram and a binding label is specified, it shall be the
+	 same as the binding label specified in the corresponding module
+	 procedure interface body.  */
+      if (sym->attr.module_procedure && sym->old_symbol
+  	  && strcmp (sym->name, sym->old_symbol->name) == 0
+	  && strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
+	{
+	  const char *null = "NULL", *s1, *s2;
+	  s1 = sym->binding_label;
+	  if (!s1) s1 = null;
+	  s2 = sym->old_symbol->binding_label;
+	  if (!s2) s2 = null;
+          gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
+	  sym->refs++;	/* Needed to avoid an ICE in gfc_release_symbol */
+	  return MATCH_ERROR;
+	}
 
       /* Scan the dummy arguments for an alternate return.  */
       for (arg = sym->formal; arg; arg = arg->next)
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: gcc/testsuite/gfortran.dg/pr89943_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr89943_3.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr89943_3.f90	(working copy)
@@ -0,0 +1,28 @@
+! { dg-do compile }
+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="runFu")   ! { dg-error "Mismatch in BIND" }
+         use, intrinsic :: iso_c_binding                 ! { dg-error "Unexpected USE statement" }
+         implicit none                                   ! { dg-error "Unexpected IMPLICIT NONE statement" }
+         integer(c_int32_t) , intent(in) :: ndim         ! { dg-error "Unexpected data declaration" }
+      end subroutine runFoo4C                            ! { dg-error " Expecting END SUBMODULE" }
+
+end submodule Foo_smod
Index: gcc/testsuite/gfortran.dg/pr89943_4.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr89943_4.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr89943_4.f90	(working copy)
@@ -0,0 +1,29 @@
+! { dg-do compile }
+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="runFu")  ! { dg-error "Mismatch in BIND" }
+         use, intrinsic :: iso_c_binding     ! { dg-error "Unexpected USE statement in" }
+         implicit none                       ! { dg-error "Unexpected IMPLICIT NONE statement" }
+         integer(c_int32_t) , intent(in) :: ndim   ! { dg-error "Unexpected data declaration" }
+      end function runFoo4C                  ! { dg-error "Expecting END SUBMODULE" }
+
+end submodule Foo_smod

  reply	other threads:[~2019-10-14 20:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-04 22:26 Steve Kargl
2019-10-11 18:50 ` Steve Kargl
2019-10-12 14:22   ` Paul Richard Thomas
2019-10-14 20:09     ` Steve Kargl [this message]
2019-10-14 20:25       ` Paul Richard Thomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191014200624.GA39911@troutmask.apl.washington.edu \
    --to=sgk@troutmask.apl.washington.edu \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=paul.richard.thomas@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).