[Bug fortran/46974] ICE with TRANSFER using a C_PTR entity

2010-12-20 Thread burnus at gcc dot gnu.org
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

2010-12-19 Thread burnus at gcc dot gnu.org
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

2010-12-18 Thread burnus at gcc dot gnu.org
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

2010-12-18 Thread burnus at gcc dot gnu.org
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

2010-12-18 Thread sgk at troutmask dot apl.washington.edu
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

2010-12-18 Thread burnus at gcc dot gnu.org
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

2010-12-18 Thread burnus at gcc dot gnu.org
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

2010-12-18 Thread burnus at gcc dot gnu.org
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

2010-12-17 Thread sgk at troutmask dot apl.washington.edu
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

2010-12-17 Thread sgk at troutmask dot apl.washington.edu
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

2010-12-17 Thread kargl at gcc dot gnu.org
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?