[F-E, patch]: bug fixes for type components, etc.
Christopher D. Rickett
crickett@lanl.gov
Fri Jun 8 01:01:00 GMT 2007
hi all,
the attached patch mainly fixes bugs found by Tobias for bind(c) derived
types that have pointer/allocatable components.
bootstrapped and regtested on x86 with no new failures.
ChangeLog entry:
2007-06-07 Christopher D. Rickett <crickett@lanl.gov>
* trans-expr.c (gfc_conv_initializer): Combined if statements.
* symbol.c (verify_bind_c_derived_type): Fixed bugs with POINTER
and ALLOCATABLE components. Add check to prevent duplicate
checking of a C interoperable derived type. Change "can not" to
"cannot".
* gfortran.dg/bind_c_dts_3.f03: Added new tests for POINTER and
ALLOCATABLE components.
Chris
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/bind_c_dts_3.f03
===================================================================
--- gcc/testsuite/gfortran.dg/bind_c_dts_3.f03 (revision 125544)
+++ gcc/testsuite/gfortran.dg/bind_c_dts_3.f03 (working copy)
@@ -3,6 +3,10 @@ module bind_c_dts_3
use, intrinsic :: iso_c_binding
implicit none
+TYPE, bind(c) :: t
+ integer(c_int) :: i
+end type t
+
type :: my_c_type_0 ! { dg-error "must have the BIND attribute" }
integer(c_int) :: i
end type my_c_type_0
@@ -13,6 +17,14 @@ type, bind(c) :: my_c_type_1 ! { dg-erro
integer(c_int), pointer :: j ! { dg-error "cannot have the POINTER" }
end type my_c_type_1
+type, bind(c) :: t2 ! { dg-error "BIND.C. derived type" }
+ type (t2), pointer :: next ! { dg-error "cannot have the POINTER" }
+end type t2
+
+type, bind(c):: t3 ! { dg-error "BIND.C. derived type" }
+ type(t), allocatable :: c(:) ! { dg-error "cannot have the ALLOCATABLE" }
+end type t3
+
contains
subroutine sub0(my_type, expected_value) bind(c) ! { dg-error "is not C interoperable" }
type(my_c_type_1) :: my_type
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c (revision 125544)
+++ gcc/fortran/trans-expr.c (working copy)
@@ -2755,9 +2755,9 @@ gfc_conv_initializer (gfc_expr * expr, g
return NULL_TREE;
if (expr != NULL && expr->ts.type == BT_DERIVED
- && expr->ts.is_iso_c && expr->ts.derived)
- if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
- || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
+ && expr->ts.is_iso_c && expr->ts.derived
+ && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
+ || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR))
expr = gfc_int_expr (0);
if (array)
@@ -3159,8 +3159,8 @@ gfc_conv_expr (gfc_se * se, gfc_expr * e
if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
|| expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
{
- /* Try simply setting expr_type to EXPR_NULL, which should result
- in null_pointer_node being used below. */
+ /* Set expr_type to EXPR_NULL, which will result in
+ null_pointer_node being used below. */
expr->expr_type = EXPR_NULL;
}
else
Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c (revision 125544)
+++ gcc/fortran/symbol.c (working copy)
@@ -27,6 +27,7 @@ Software Foundation, 51 Franklin Street,
#include "gfortran.h"
#include "parse.h"
+
/* Strings for all symbol attributes. We use these for dumping the
parse tree, in error messages, and also when reading and writing
modules. */
@@ -3006,6 +3007,11 @@ verify_bind_c_derived_type (gfc_symbol *
gfc_internal_error ("verify_bind_c_derived_type(): Given symbol is "
"unexpectedly NULL");
+ /* If we've already looked at this derived symbol, do not look at it again
+ so we don't repeat warnings/errors. */
+ if (derived_sym->ts.is_c_interop)
+ return SUCCESS;
+
/* The derived type must have the BIND attribute to be interoperable
J3/04-007, Section 15.2.3. */
if (derived_sym->attr.is_bind_c != 1)
@@ -3035,10 +3041,34 @@ verify_bind_c_derived_type (gfc_symbol *
each is a C interoperable type. */
do
{
- /* BIND(C) derived types can't have derived types in them unless
- they're c_ptr or c_funptr. J3/04-007, Section 15.2.3, C1502. */
+ /* The components cannot be pointers (fortran sense).
+ J3/04-007, Section 15.2.3, C1505. */
+ if (curr_comp->pointer != 0)
+ {
+ gfc_error ("Component '%s' at %L cannot have the "
+ "POINTER attribute because it is a member "
+ "of the BIND(C) derived type '%s' at %L",
+ curr_comp->name, &(curr_comp->loc),
+ derived_sym->name, &(derived_sym->declared_at));
+ retval = FAILURE;
+ }
+
+ /* The components cannot be allocatable.
+ J3/04-007, Section 15.2.3, C1505. */
+ if (curr_comp->allocatable != 0)
+ {
+ gfc_error ("Component '%s' at %L cannot have the "
+ "ALLOCATABLE attribute because it is a member "
+ "of the BIND(C) derived type '%s' at %L",
+ curr_comp->name, &(curr_comp->loc),
+ derived_sym->name, &(derived_sym->declared_at));
+ retval = FAILURE;
+ }
+
+ /* BIND(C) derived types must have interoperable components. */
if (curr_comp->ts.type == BT_DERIVED
- && curr_comp->ts.derived->ts.is_iso_c != 1)
+ && curr_comp->ts.derived->ts.is_iso_c != 1
+ && curr_comp->ts.derived != derived_sym)
{
/* This should be allowed; the draft says a derived-type can not
have type parameters if it is has the BIND attribute. Type
@@ -3080,30 +3110,6 @@ verify_bind_c_derived_type (gfc_symbol *
curr_comp->name, derived_sym->name,
&(curr_comp->loc));
}
-
- /* The components can not be pointers (fortran sense).
- J3/04-007, Section 15.2.3, C1505. */
- if (curr_comp->pointer != 0)
- {
- gfc_error ("Component '%s' at %L cannot have the "
- "POINTER attribute because it is a member "
- "of the BIND(C) derived type '%s' at %L",
- curr_comp->name, &(curr_comp->loc),
- derived_sym->name, &(derived_sym->declared_at));
- retval = FAILURE;
- }
-
- /* The components can not be allocatable.
- J3/04-007, Section 15.2.3, C1505. */
- if (curr_comp->allocatable != 0)
- {
- gfc_error ("Component '%s' at %L cannot have the "
- "ALLOCATABLE attribute because it is a member "
- "of the BIND(C) derived type '%s' at %L",
- curr_comp->name, &(curr_comp->loc),
- derived_sym->name, &(derived_sym->declared_at));
- retval = FAILURE;
- }
}
curr_comp = curr_comp->next;
@@ -3181,8 +3187,8 @@ gen_special_c_interop_ptr (int ptr_id, c
generate_isocbinding_symbol (module_name, ptr_id == ISOCBINDING_NULL_PTR
? ISOCBINDING_PTR : ISOCBINDING_FUNPTR,
(char *) (ptr_id == ISOCBINDING_NULL_PTR
- ? "_gfortran_iso_c_binding_c_ptr"
- : "_gfortran_iso_c_binding_c_funptr"));
+ ? "_gfortran_iso_c_binding_c_ptr" :
+ "_gfortran_iso_c_binding_c_funptr"));
tmp_sym->ts.derived =
get_iso_c_binding_dt (ptr_id == ISOCBINDING_NULL_PTR
@@ -3723,8 +3729,8 @@ generate_isocbinding_symbol (const char
(mod_name, s == ISOCBINDING_FUNLOC
? ISOCBINDING_FUNPTR : ISOCBINDING_FUNPTR,
(char *)(s == ISOCBINDING_FUNLOC
- ? "_gfortran_iso_c_binding_c_funptr"
- : "_gfortran_iso_c_binding_c_ptr"));
+ ? "_gfortran_iso_c_binding_c_funptr" :
+ "_gfortran_iso_c_binding_c_ptr"));
tmp_sym->ts.derived =
get_iso_c_binding_dt (s == ISOCBINDING_FUNLOC
? ISOCBINDING_FUNPTR
More information about the Fortran
mailing list