This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/34199] segfault for TRANSFER integer to TYPE(C_PTR)
- From: "fxcoudert at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 Feb 2008 14:04:05 -0000
- Subject: [Bug fortran/34199] segfault for TRANSFER integer to TYPE(C_PTR)
- References: <bug-34199-13404@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #3 from fxcoudert at gcc dot gnu dot org 2008-02-24 14:04 -------
The ICE itself can be gotten rid of by setting the offset of the private field
of our ISO_C derived types:
Index: trans-types.c
===================================================================
--- trans-types.c (revision 132578)
+++ trans-types.c (working copy)
@@ -1731,6 +1731,7 @@
get_identifier (derived->components->name),
gfc_typenode_for_spec (
&(derived->components->ts)));
+ DECL_FIELD_OFFSET (derived->components->backend_decl) = size_int (0);
derived->ts.kind = gfc_index_integer_kind;
derived->ts.type = BT_INTEGER;
(Independently of the rest, I think that fix is desirable.) However, with that
fix, we now error out:
C_NULL_PTR1 = transfer(0_C_INTPTR_T, C_NULL_PTR1)
1
Error: Can't convert INTEGER(4) to TYPE(c_ptr) at (1)
The reason for that is that gfc_typenode_for_spec(), which is called from
gfc_interpret_derived(), modifies the symbol itself to make it an integer:
/* If we're dealing with either C_PTR or C_FUNPTR, we modified the
type and kind to fit a (void *) and the basetype returned was a
ptr_type_node. We need to pass up this new information to the
symbol that was declared of type C_PTR or C_FUNPTR. */
I have always been wary of this course of actions (magically making the
ISO_C_BINDING derived types into scalar integer variables), and in that case it
is biting us hard. I have tried to work around this in target-memory.c by a
custom-tailored fix:
Index: target-memory.c
===================================================================
--- target-memory.c (revision 132578)
+++ target-memory.c (working copy)
@@ -379,7 +379,21 @@
/* The attributes of the derived type need to be bolted to the floor. */
result->expr_type = EXPR_STRUCTURE;
- type = gfc_typenode_for_spec (&result->ts);
+ /* FIXME -- This is more of a workaround than a real fix, please see
+ PR34199 for details.
+ For ISO_C_BINDING derived types, gfc_typenode_for_spec() will change
+ the symbol under our feet into an integer, which we don't want, so
+ we restore it. */
+ if (result->ts.type == BT_DERIVED && result->ts.derived->attr.is_iso_c)
+ {
+ gfc_typespec ts;
+ ts = result->ts;
+ type = gfc_typenode_for_spec (&result->ts);
+ result->ts = ts;
+ }
+ else
+ type = gfc_typenode_for_spec (&result->ts);
+
cmp = result->ts.derived->components;
/* Run through the derived type components. */
This in turn makes the derived type constructors go into trans-expr.c's
gfc_conv_expr(), which does not deal with them. This is fixed with the
following patchlet:
Index: trans-expr.c
===================================================================
--- trans-expr.c (revision 132578)
+++ trans-expr.c (working copy)
@@ -3517,14 +3517,19 @@
}
/* We need to convert the expressions for the iso_c_binding derived types.
- C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
- null_pointer_node. C_PTR and C_FUNPTR are converted to match the
- typespec for the C_PTR and C_FUNPTR symbols, which has already been
- updated to be an integer with a kind equal to the size of a (void *). */
+ C_NULL_PTR, C_NULL_FUNPTR and constants (coming, for example, from the
+ simplification of TRANSFER expressions) will be made EXPR_NULL,
+ which evaluates to null_pointer_node. C_PTR and C_FUNPTR are converted
+ to match the typespec for the C_PTR and C_FUNPTR symbols, which has
+ already been updated to be an integer with a kind equal to the size of
+ a (void *). */
if (expr->ts.type == BT_DERIVED && expr->ts.derived
&& expr->ts.derived->attr.is_iso_c)
{
- if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
+ /* expr->expr_type == EXPR_STRUCTURE matches the constant derived
+ types. */
+ if (expr->expr_type == EXPR_STRUCTURE
+ || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
|| expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
{
/* Set expr_type to EXPR_NULL, which will result in
Now, with all three patches, we can compile the testcase and run it fine. I'm
not really satisfied with the patch to target-memory.c, as it is more a
workaround than a patch. For that reason, I'm not assigning this to myself and
will let the ISO_C_BINDING experts decide what course is most appropriate.
--
fxcoudert at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |fxcoudert at gcc dot gnu dot
| |org
Keywords| |patch
Last reconfirmed|2007-11-25 03:11:32 |2008-02-24 14:04:05
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34199