Patchwork [fortran] allow an empty derived type with a bind(c) attribute

login
register
mail settings
Submitter Steve Kargl
Date Nov. 11, 2010, 6:19 p.m.
Message ID <20101111181952.GA79361@troutmask.apl.washington.edu>
Download mbox | patch
Permalink /patch/70848/
State New
Headers show

Comments

Steve Kargl - Nov. 11, 2010, 6:19 p.m.
The attached patch has been built and regression tested on
i686-*-freebsd.  There were no regression observed with this
patch.  So, what does it do?

Fortran 2003 allows a derived type to be empty.  It so happens
that one can also add the BIND(C) attribute to the derived type.
The simple example is in the empty_derived_type.f90 testcase:

  ! { dg-do compile }
  module stuff
    implicit none
    type, bind(C) :: junk ! { dg-warning "inaccessible by the C companion" }
       ! Empty!
    end type junk
  end module stuff 

gfortran currently disallows the above code with

troutmask:sgk[203] gfc4x -c po.f90 
po.f90:4.82:

, bind(C) :: junk ! { dg-warning "inaccessible by the C companion" }
                                                                           1       
Error: Derived type 'junk' at (1) is empty

(Side note:  The error message above is mangled!)

With the attached patch, the error is degraded to a warning, thusly,

laptop:kargl[219] gfc4x -c po.f90
po.f90:4.24:

   type, bind(C) :: junk
                        1
Warning: Derived type 'junk' with BIND(C) attribute at (1) is empty, and
may be inaccessible by the C companion processor

So, what's this business about a C companion processor?  A structure 
cannot be empty, 

laptop:kargl[223] cat k.c
#include <stdio.h>
int main()
{
   struct junk
   {
      // empty!
   };
   struct junk x;
   printf("Hello, world!\n");
   return 0;
}
laptop:kargl[224] cc -o z k.c
laptop:kargl[225] ./z
Hello, world!

except gcc accepts the invalid code as an extension without warning or error!

laptop:kargl[226] cc -o z -pedantic k.c
k.c: In function 'main':
k.c:8: warning: struct has no members

It seems 'pedantic' does not mean that gcc should pedantically follow the
C standard.  The C code is invalid!

   /* Invalid.  struct contains no member. */
   struct junk
   {
      // empty!
   };

   /* Valid. struct is nonempty, contains an unnamed member, is not
      interoperable with Fortran. */
   struct junk
   {
      int : 0;
   };

   /* Valid. struct is nonempty, contains a named member, is
      interoperable with Fortran. */
   struct junk
   {
      int x;
   };

For more information see

http://groups.google.com/group/comp.lang.fortran/browse_frm/thread/5acfb0c37d904e86#


2010-11-10  Steven G. Kargl <kargl@gcc.gnu.org>

	* symbol.c (verify_bind_c_derived_type):  Accept BIND(C) on an empty
	derived type.

2010-11-10  Steven G. Kargl <kargl@gcc.gnu.org>

	* gfortran.dg/empty_derived_type.f90: New test.

OK for trunk?
Tobias Burnus - Nov. 11, 2010, 9:15 p.m.
Steve Kargl write:
> 2010-11-10  Steven G. Kargl<kargl@gcc.gnu.org>
>
> 	* symbol.c (verify_bind_c_derived_type):  Accept BIND(C) on an empty
> 	derived type.
>
> 2010-11-10  Steven G. Kargl<kargl@gcc.gnu.org>
>
> 	* gfortran.dg/empty_derived_type.f90: New test.
>
> OK for trunk?

OK. Thanks for the patch.

Tobias

Patch

Index: gcc/testsuite/gfortran.dg/empty_derived_type.f90
===================================================================
--- gcc/testsuite/gfortran.dg/empty_derived_type.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/empty_derived_type.f90	(revision 0)
@@ -0,0 +1,7 @@ 
+! { dg-do compile }
+module stuff
+   implicit none
+   type, bind(C) :: junk ! { dg-warning "may be inaccessible by the C companion" }
+      ! Empty!
+   end type junk
+end module stuff 
Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c	(revision 166545)
+++ gcc/fortran/symbol.c	(working copy)
@@ -3592,14 +3592,25 @@  verify_bind_c_derived_type (gfc_symbol *
   
   curr_comp = derived_sym->components;
 
-  /* TODO: is this really an error?  */
+  /* Fortran 2003 allows an empty derived type.  C99 appears to disallow an
+     empty struct.  Section 15.2 in Fortran 2003 states:  "The following
+     subclauses define the conditions under which a Fortran entity is
+     interoperable.  If a Fortran entity is interoperable, an equivalent
+     entity may be defined by means of C and the Fortran entity is said
+     to be interoperable with the C entity.  There does not have to be such
+     an interoperating C entity."
+  */
   if (curr_comp == NULL)
     {
-      gfc_error ("Derived type '%s' at %L is empty",
-		 derived_sym->name, &(derived_sym->declared_at));
-      return FAILURE;
+      gfc_warning ("Derived type '%s' with BIND(C) attribute at %L is empty, "
+		   "and may be inaccessible by the C companion processor",
+		   derived_sym->name, &(derived_sym->declared_at));
+      derived_sym->ts.is_c_interop = 1;
+      derived_sym->attr.is_bind_c = 1;
+      return SUCCESS;
     }
 
+
   /* Initialize the derived type as being C interoperable.
      If we find an error in the components, this will be set false.  */
   derived_sym->ts.is_c_interop = 1;