Patchwork [Fortran] -std=f2008tr, TR 29113 and OPTIONAL arguments with BIND(C)

login
register
mail settings
Submitter Tobias Burnus
Date May 5, 2011, 5:45 a.m.
Message ID <4DC23986.6080904@net-b.de>
Download mbox | patch
Permalink /patch/94202/
State New
Headers show

Comments

Tobias Burnus - May 5, 2011, 5:45 a.m.
This patch does the first minor steps towards TR 29113: It accepts the 
OPTIONAL attribute in procedures with C binding. As gfortran already 
passes absent arguments a NULL pointer, there is no changed needed, 
except in the diagnostics part. Additionally, it is a feature also 
supported by other compilers.

Additionally, this patch adds the option -std=f2008tr (tr = Technical 
Report(s)), which is supposed to cover Fortran 2008 and the two 
technical reports, TR 29113 (further interop with C) and the TR about 
enhanced coarray support.

I think it would be nice if TYPE(*) and DIMENSION(..) could also be 
implemented during the 4.7 development period as they are useful for C 
interoperability ("void *buffer") - and in particular for MPI 3; 
additionally, they do not seem to be that difficult to implement. 
However, I do not plan to work on them in the near future.

Build and regtested on x86-64-linux
OK for the trunk?

The implementation status will be tracked at 
http://gcc.gnu.org/wiki/TR29113Status ;-)

Tobias

PS: I included in the patch also a patchlet for IMPORT, cf. Mikael's 
comment at http://gcc.gnu.org/ml/fortran/2011-05/msg00005.html; with 
that patch, "sym" is always set to NULL when entering the loop for the 
next symbol. I think it is not really needed as "gfc_current_ns->parent" 
should be always "!= NULL", but maybe one manages have it NULL.
Tobias Burnus - May 5, 2011, 8:17 p.m.
> Build and regtested on x86-64-linux
> OK for the trunk?

I forgot to include a run-time test case. Find one attached.

Tobias
! { dg-do run }
! { dg-additional-sources bind_c_usage_24_c.c }
!
! PR fortran/48858
! PR fortran/48820
!
! TR 29113: BIND(C) with OPTIONAL
!
module m
  use iso_c_binding
  interface
    subroutine c_proc (is_present, var) bind(C)
      import
      logical(c_bool), value    :: is_present
      integer(c_int),  optional :: var
    end subroutine
  end interface
contains
  subroutine subtest (is_present, var) bind(C)
    logical(c_bool), intent(in),    value    :: is_present
    integer(c_int),  intent(inout), optional :: var
    if (is_present) then
      if (.not. present (var)) call abort ()
      if (var /= 43) call abort ()
      var = -45
    else
      if (present (var)) call abort ()
    end if
  end subroutine subtest
end module m

program test
  use m
  implicit none
  integer :: val

  val = 4
  call c_proc (.false._c_bool)
  call c_proc (.true._c_bool, val)
  if (val /= 7) call abort ()
end program test

! { dg-final { cleanup-modules "m" } }
Jerry DeLisle - May 6, 2011, 4:18 p.m.
On 05/04/2011 10:45 PM, Tobias Burnus wrote:
> This patch does the first minor steps towards TR 29113: It accepts the OPTIONAL
> attribute in procedures with C binding. As gfortran already passes absent
> arguments a NULL pointer, there is no changed needed, except in the diagnostics
> part. Additionally, it is a feature also supported by other compilers.
>
> Additionally, this patch adds the option -std=f2008tr (tr = Technical
> Report(s)), which is supposed to cover Fortran 2008 and the two technical
> reports, TR 29113 (further interop with C) and the TR about enhanced coarray
> support.
>
> I think it would be nice if TYPE(*) and DIMENSION(..) could also be implemented
> during the 4.7 development period as they are useful for C interoperability
> ("void *buffer") - and in particular for MPI 3; additionally, they do not seem
> to be that difficult to implement. However, I do not plan to work on them in the
> near future.
>
> Build and regtested on x86-64-linux
> OK for the trunk?

OK, thanks for the start.

Jerry

Patch

2011-05-04  Tobias Burnus  <burnus@net-b.de>

	PR fortran/48858
	PR fortran/48820
	* lang.opt (std=f2008tr): New.
	* libgfortran.h (GFC_STD_F2008_TR): New macro constant.
	* decl.c (verify_c_interop_param): Allow OPTIONAL in BIND(C)
	procedures for -std=f2008tr/gnu/legacy.
	(gfc_match_import): Set sym to NULL.
	* options.c (set_default_std_flags,gfc_handle_option): Handle
	-std=f2008tr.
	* invoke.texi (-std=): Document -std=f2008tr.

2011-05-04  Tobias Burnus  <burnus@net-b.de>

	PR fortran/48858
	PR fortran/48820
	* gfortran.dg/bind_c_usage_22.f90: New.
	* gfortran.dg/bind_c_usage_23.f90: New.

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index dfbca29..8acd594 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -1060,14 +1060,22 @@  verify_c_interop_param (gfc_symbol *sym)
 	      retval = FAILURE;
 	    }
 
-	  if (sym->attr.optional == 1)
+	  if (sym->attr.optional == 1 && sym->attr.value)
 	    {
-	      gfc_error ("Variable '%s' at %L cannot have the "
-			 "OPTIONAL attribute because procedure '%s'"
-			 " is BIND(C)", sym->name, &(sym->declared_at),
+	      gfc_error ("Variable '%s' at %L cannot have both the OPTIONAL "
+			 "and the VALUE attribute because procedure '%s' "
+			 "is BIND(C)", sym->name, &(sym->declared_at),
 			 sym->ns->proc_name->name);
 	      retval = FAILURE;
 	    }
+	  else if (sym->attr.optional == 1
+		   && gfc_notify_std (GFC_STD_F2008_TR, "TR29113: Variable '%s' "
+				      "at %L with OPTIONAL attribute in "
+				      "procedure '%s' which is BIND(C)",
+				      sym->name, &(sym->declared_at),
+				      sym->ns->proc_name->name)
+		      == FAILURE)
+	    retval = FAILURE;
 
           /* Make sure that if it has the dimension attribute, that it is
 	     either assumed size or explicit shape.  */
@@ -2985,6 +2993,7 @@  gfc_match_import (void)
 
   for(;;)
     {
+      sym = NULL;
       m = gfc_match (" %n", name);
       switch (m)
 	{
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 015493e..ce944e3 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -590,6 +590,10 @@  std=f2008
 Fortran
 Conform to the ISO Fortran 2008 standard
 
+std=f2008tr
+Fortran
+Conform to the ISO Fortran 2008 standard including TR 29113
+
 std=f95
 Fortran
 Conform to the ISO Fortran 95 standard
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index 09524d0..035a32a 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -23,6 +23,7 @@  along with GCC; see the file COPYING3.  If not see
    Note that no features were obsoleted nor deleted in F2003.
    Please remember to keep those definitions in sync with
    gfortran.texi.  */
+#define GFC_STD_F2008_TR	(1<<9)	/* POST-F2008 technical reports.  */
 #define GFC_STD_F2008_OBS	(1<<8)	/* Obsolescent in F2008.  */
 #define GFC_STD_F2008		(1<<7)	/* New in F2008.  */
 #define GFC_STD_LEGACY		(1<<6)	/* Backward compatibility.  */
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index f56fad7..ff66e0e 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -49,7 +49,7 @@  set_default_std_flags (void)
 {
   gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
     | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
-    | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY;
+    | GFC_STD_F2008_OBS | GFC_STD_F2008_TR | GFC_STD_GNU | GFC_STD_LEGACY;
   gfc_option.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY;
 }
 
@@ -942,6 +945,16 @@  gfc_handle_option (size_t scode, const char *arg, int value,
       gfc_option.warn_tabs = 0;
       break;
 
+    case OPT_std_f2008tr:
+      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
+	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS
+	| GFC_STD_F2008_TR;
+      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
+      gfc_option.max_identifier_length = 63;
+      gfc_option.warn_ampersand = 1;
+      gfc_option.warn_tabs = 0;
+      break;
+
     case OPT_std_gnu:
       set_default_std_flags ();
       break;
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 0874e5c..655df12 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -368,7 +368,9 @@  extensions, and may be useful for old non-standard programs.  The
 conformance to the Fortran 95, Fortran 2003 and Fortran 2008 standards,
 respectively; errors are given for all extensions beyond the relevant
 language standard, and warnings are given for the Fortran 77 features
-that are permitted but obsolescent in later standards.
+that are permitted but obsolescent in later standards. @samp{-std=f2008tr}
+allows the Fortran 2008 standard including the additions of the 
+technical report (TR) 29113.
 
 @end table
 
--- /dev/null	2011-05-03 23:04:54.143891387 +0200
+++ gcc/gcc/testsuite/gfortran.dg/bind_c_usage_22.f90	2011-05-04 19:52:31.000000000 +0200
@@ -0,0 +1,64 @@ 
+! { dg-do compile }
+! { dg-options "-std=f2008tr" }
+!
+! PR fortran/48858
+! PR fortran/48820
+!
+! OPTIONAL + BIND(C) is allowed since TR 29113
+!
+
+! VALID
+subroutine sub(z) bind(C)
+  use iso_c_binding
+  integer(c_int), value :: z
+end subroutine sub
+
+! VALID since TR29113
+subroutine sub2(z) bind(C)
+  use iso_c_binding
+  integer(c_int), optional :: z
+end subroutine sub2
+
+! VALID since TR29113
+subroutine sub2a(z) bind(C)
+  use iso_c_binding
+  integer(c_int) :: z
+  optional :: z
+end subroutine sub2a
+
+! VALID since TR29113
+subroutine sub2b(z) bind(C)
+  use iso_c_binding
+  optional :: z
+  integer(c_int) :: z
+end subroutine sub2b
+
+! Invalid
+subroutine sub3(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  integer(c_int), value, optional :: z
+end subroutine sub3
+
+! Invalid
+subroutine sub3a(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  integer(c_int) :: z
+  optional :: z
+  value :: z
+end subroutine sub3a
+
+! Invalid
+subroutine sub3b(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  optional :: z
+  value :: z
+  integer(c_int) :: z
+end subroutine sub3b
+
+! Invalid
+subroutine sub3c(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  value :: z
+  integer(c_int) :: z
+  optional :: z
+end subroutine sub3c
--- /dev/null	2011-05-03 23:04:54.143891387 +0200
+++ gcc/gcc/testsuite/gfortran.dg/bind_c_usage_23.f90	2011-05-04 19:53:24.000000000 +0200
@@ -0,0 +1,64 @@ 
+! { dg-do compile }
+! { dg-options "-std=f2008" }
+!
+! PR fortran/48858
+! PR fortran/48820
+!
+! OPTIONAL + BIND(C) is allowed since TR 29113
+!
+
+! VALID
+subroutine sub(z) bind(C)
+  use iso_c_binding
+  integer(c_int), value :: z
+end subroutine sub
+
+! VALID since TR29113
+subroutine sub2(z) bind(C) ! { dg-error "with OPTIONAL attribute in procedure" }
+  use iso_c_binding
+  integer(c_int), optional :: z
+end subroutine sub2
+
+! VALID since TR29113
+subroutine sub2a(z) bind(C) ! { dg-error "with OPTIONAL attribute in procedure" }
+  use iso_c_binding
+  integer(c_int) :: z
+  optional :: z
+end subroutine sub2a
+
+! VALID since TR29113
+subroutine sub2b(z) bind(C) ! { dg-error "with OPTIONAL attribute in procedure" }
+  use iso_c_binding
+  optional :: z
+  integer(c_int) :: z
+end subroutine sub2b
+
+! Invalid
+subroutine sub3(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  integer(c_int), value, optional :: z
+end subroutine sub3
+
+! Invalid
+subroutine sub3a(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  integer(c_int) :: z
+  optional :: z
+  value :: z
+end subroutine sub3a
+
+! Invalid
+subroutine sub3b(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  optional :: z
+  value :: z
+  integer(c_int) :: z
+end subroutine sub3b
+
+! Invalid
+subroutine sub3c(z) bind(C) ! { dg-error "cannot have both the OPTIONAL and the VALUE attribute" }
+  use iso_c_binding
+  value :: z
+  integer(c_int) :: z
+  optional :: z
+end subroutine sub3c