This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, fortran] allow an empty derived type with a bind(c) attribute
- From: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Thu, 11 Nov 2010 10:19:52 -0800
- Subject: [PATCH, fortran] allow an empty derived type with a bind(c) attribute
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?
--
steve
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;