[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #11 from Tobias Burnus 2010-12-20 21:44:02 UTC --- Author: burnus Date: Mon Dec 20 21:43:58 2010 New Revision: 168095 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168095 Log: 2010-12-20 Tobias Burnus PR fortran/46974 * gfortran.dg/c_ptr_tests_16.f90: Fix endian issue. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_16.f90
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #10 from Tobias Burnus 2010-12-19 11:24:34 UTC --- *** Bug 34199 has been marked as a duplicate of this bug. ***
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 Tobias Burnus changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||FIXED --- Comment #9 from Tobias Burnus 2010-12-18 20:26:07 UTC --- FIXED on the trunk (4.6).
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #8 from Tobias Burnus 2010-12-18 20:18:47 UTC --- Author: burnus Date: Sat Dec 18 20:18:43 2010 New Revision: 168031 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168031 Log: 2010-12-18 Tobias Burnus PR fortran/46974 * target-memory.c (gfc_interpret_derived): Handle * C_PTR/C_FUNPTR. * trans-expr.c (gfc_trans_structure_assign): Ditto. (gfc_conv_expr): Avoid crashes using non-C_NULL_(FUN)PTR const expr. 2010-12-18 Tobias Burnus PR fortran/46974 * gfortran.dg/c_ptr_tests_16.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/c_ptr_tests_16.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/target-memory.c trunk/gcc/fortran/trans-expr.c trunk/gcc/testsuite/ChangeLog
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #7 from Steve Kargl 2010-12-18 17:10:59 UTC --- On Sat, Dec 18, 2010 at 10:07:51AM +, burnus at gcc dot gnu.org wrote: > > --- Comment #4 from Tobias Burnus 2010-12-18 > 10:07:33 UTC --- > (In reply to comment #3) > > + if ((mold->expr_type == EXPR_VARIABLE || mold->expr_type == > > EXPR_STRUCTURE) > > + && mold->ts.type == BT_DERIVED && mold->ts.u.derived > > + && (strcmp(mold->ts.u.derived->name, "c_ptr") == 0 > > + || strcmp(mold->ts.u.derived->name, "c_funptr") == 0)) > > +return NULL; > > + > > Won't this cause problems with user-defined types with the same name? A check for mold->ts.u.derived->attr.is_iso_c could be added, but yes I agree that this appears to somewhat hackish. In fact, the patch fails in a interesting way with a new piece of code from James. program bug6 use ISO_C_BINDING implicit none interface function fun() use ISO_C_BINDING implicit none type(C_FUNPTR) fun end function fun end interface type(C_PTR) array(2) type(C_FUNPTR) result integer(C_INTPTR_T), parameter :: const(*) = [32512,32520] result = fun() array = transfer([integer(C_INTPTR_T)::32512,32520],array) ! write(*,*) transfer(result,const) ! write(*,*) transfer(array,const) end program bug6 function fun() use ISO_C_BINDING implicit none type(C_FUNPTR) fun fun = transfer(32512_C_INTPTR_T,fun) end function fun With this code, mold->ts.type is BT_INTEGER, the backend_decl is NULL, and mold->ts.u.derived contains the information that we need. So, yes, creating a proper backend_decl when C_PTR or C_FUNPTR is parsed/resolved is probably the correct solution. Unfortunately, I don't know how or where to do that. :(
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #6 from Tobias Burnus 2010-12-18 16:21:00 UTC --- (In reply to comment #5) > Draft patch: Which of course does not work ...
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #5 from Tobias Burnus 2010-12-18 15:38:18 UTC --- Draft patch: --- a/gcc/fortran/target-memory.c +++ b/gcc/fortran/target-memory.c @@ -445,6 +445,21 @@ gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *resu type = gfc_typenode_for_spec (&result->ts); cmp = result->ts.u.derived->components; + if (result->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING + && (result->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR + || result->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR)) +{ + gfc_constructor *c; + gfc_expr *e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind, + &result->where); + c = gfc_constructor_append_expr (&result->value.constructor, e, NULL); + c->n.component = cmp; + gfc_target_interpret_expr (buffer, buffer_size, e); + e->ts = result->ts; + e->ts.is_iso_c = 1; + return int_size_in_bytes (ptr_type_node); +} + /* Run through the derived type components. */ for (;cmp; cmp = cmp->next) {
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 Tobias Burnus changed: What|Removed |Added CC||burnus at gcc dot gnu.org --- Comment #4 from Tobias Burnus 2010-12-18 10:07:33 UTC --- (In reply to comment #3) > + if ((mold->expr_type == EXPR_VARIABLE || mold->expr_type == EXPR_STRUCTURE) > + && mold->ts.type == BT_DERIVED && mold->ts.u.derived > + && (strcmp(mold->ts.u.derived->name, "c_ptr") == 0 > + || strcmp(mold->ts.u.derived->name, "c_funptr") == 0)) > +return NULL; > + Won't this cause problems with user-defined types with the same name? Additionally, I would rather bring C_PTR/C_FUNPTR closer a normal derived type (which is only in the last step treated specially) than to introduce hacks like that. The reason for the crash is that in gfc_interpret_derived the pointer component of "c_ptr" ("__c_ptr_c_address") has no backend declaration (cmp->backend_decl == NULL) - and thus "ptr = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (cmp->backend_decl))" crashes. Maybe it is sufficient to set it via gfc_typenode_for_spec in that function. I think the advantage of fixing this part of the code is that one can simplify the code at compile time - which is usually preferred to run-time evaluation.
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #3 from Steve Kargl 2010-12-18 06:45:19 UTC --- On Sat, Dec 18, 2010 at 12:01:13AM +, sgk at troutmask dot apl.washington.edu wrote: > > Index: simplify.c > === > --- simplify.c (revision 167949) > +++ simplify.c (working copy) > @@ -5954,6 +5954,11 @@ gfc_simplify_transfer (gfc_expr *source, >if (source->expr_type == EXPR_FUNCTION) > return NULL; > > + if ((mold->expr_type == EXPR_VARIABLE || mold->expr_type == EXPR_STRUCTURE) > + && mold->ts.type == BT_DERIVED && mold->ts.u.derived > + && strcmp(mold->ts.u.derived->name, "c_ptr") == 0) > +return NULL; > + >/* Calculate the size of the source. */ >if (source->expr_type == EXPR_ARRAY >&& gfc_array_size (source, &tmp) == FAILURE) Updated patch to hand C_FUNPTR types. Index: simplify.c === --- simplify.c (revision 167949) +++ simplify.c (working copy) @@ -5954,6 +5954,12 @@ gfc_simplify_transfer (gfc_expr *source, if (source->expr_type == EXPR_FUNCTION) return NULL; + if ((mold->expr_type == EXPR_VARIABLE || mold->expr_type == EXPR_STRUCTURE) + && mold->ts.type == BT_DERIVED && mold->ts.u.derived + && (strcmp(mold->ts.u.derived->name, "c_ptr") == 0 + || strcmp(mold->ts.u.derived->name, "c_funptr") == 0)) +return NULL; + /* Calculate the size of the source. */ if (source->expr_type == EXPR_ARRAY && gfc_array_size (source, &tmp) == FAILURE) I suspect there may be problems with arrays and/or functions that use these derived types.
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 --- Comment #2 from Steve Kargl 2010-12-18 00:01:03 UTC --- On Fri, Dec 17, 2010 at 11:15:44PM +, kargl at gcc dot gnu.org wrote: > > Anyone know why this flag is needed? > Well, the answer is to let simplify_transfer_[34].f90 in the testsuite to compile! :-) Given program z use iso_c_binding type(c_ptr) m m = transfer(32512, m) m = transfer(32512, C_NULL_PTR) end program z This patch compiles the above. Index: simplify.c === --- simplify.c (revision 167949) +++ simplify.c (working copy) @@ -5954,6 +5954,11 @@ gfc_simplify_transfer (gfc_expr *source, if (source->expr_type == EXPR_FUNCTION) return NULL; + if ((mold->expr_type == EXPR_VARIABLE || mold->expr_type == EXPR_STRUCTURE) + && mold->ts.type == BT_DERIVED && mold->ts.u.derived + && strcmp(mold->ts.u.derived->name, "c_ptr") == 0) +return NULL; + /* Calculate the size of the source. */ if (source->expr_type == EXPR_ARRAY && gfc_array_size (source, &tmp) == FAILURE) The tree dump looks like z () --More--(74%){ void * m; { void * transfer.0; integer(kind=8) D.1524; integer(kind=8) D.1523; static integer(kind=4) C.1522 = 32512; integer(kind=8) D.1521; D.1521 = 4; D.1523 = 8; __builtin_memcpy ((void *) &transfer.0, (void *) &C.1522, MAX_EXPR , 0>); m = transfer.0; } { void * transfer.1; integer(kind=8) D.1530; integer(kind=8) D.1529; static void * C.1528 = 0B; static integer(kind=4) C.1527 = 32512; integer(kind=8) D.1526; D.1526 = 4; D.1529 = 8; __builtin_memcpy ((void *) &transfer.1, (void *) &C.1527, MAX_EXPR , 0>); m = transfer.1; } } So we are assigning a void * pointer to a void * pointer. Not sure this is the desired result.
[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46974 kargl at gcc dot gnu.org changed: What|Removed |Added CC||pault at gcc dot gnu.org --- Comment #1 from kargl at gcc dot gnu.org 2010-12-17 23:15:27 UTC --- The issues appears to have come into gfortran with pault's initial commit of Brook's gfc_simplify_transfer. This is revision 124759. Consider program z use iso_c_binding type(c_ptr) m m = transfer(12345, m) end program z The culprit is the second test in if (!gfc_is_constant_expr (source) || (gfc_init_expr_flag && !gfc_is_constant_expr (mold)) || !gfc_is_constant_expr (size)) return NULL; Here, gfc_init_expr_flag = 0 and mold is EXPR_VARIABLE, which yields !gfc_is_constant_expr (mold) = 1. Clearly (0 && anything) is going to be 0. So, gfortran tries to simplify the expression. If gfc_init_expr_flag is removed, the code compiles. Anyone know why this flag is needed?