[PATCH,fortran]: fix for PR 33395

Christopher D. Rickett crickett@lanl.gov
Tue Sep 11 20:12:00 GMT 2007


hi all,

Tobias found another bug with initialization of c_ptr components when 
building the fgsl code.  the attached patch should fix this new bug.  it 
was a simple fix; i removed a conditional in gfc_conv_initializer that was 
unnecessary because c_null_ptr and c_null_funptr are the only 
iso_c_binding derived types that can be used as initializers.

bootstrapped and regtested on x86 and x86_64 linux with no new failures.

thanks.
Chris

:ADDPATCH fortran:

ChangeLog entry:

2007-09-11  Christopher D. Rickett  <crickett@lanl.gov>

 	PR fortran/33395
 	* trans-expr.c (gfc_conv_initializer): Remove unnecessary test for
 	intmod_sym_id and use derived symbol to set new kind of C_NULL_PTR
 	and C_NULL_FUNPTR expressions.

2007-09-11  Christopher D. Rickett  <crickett@lanl.gov>

 	PR fortran/33395
 	* gfortran.dg/c_ptr_tests_12.f03: New test case.
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/c_ptr_tests_12.f03
===================================================================
--- gcc/testsuite/gfortran.dg/c_ptr_tests_12.f03	(revision 0)
+++ gcc/testsuite/gfortran.dg/c_ptr_tests_12.f03	(revision 0)
@@ -0,0 +1,45 @@
+! { dg-do compile }
+! Verify that initialization of c_ptr components works.  This is based on 
+! code from fgsl: 
+! http://www.lrz-muenchen.de/services/software/mathematik/gsl/fortran/
+! and tests PR 33395.
+module fgsl
+  use, intrinsic :: iso_c_binding
+  implicit none
+!
+!
+! Kind and length parameters are default integer
+!
+  integer, parameter, public :: fgsl_double = c_double
+
+!
+! Types : Array support
+!
+  type, public :: fgsl_vector
+     private
+     type(c_ptr) :: gsl_vector = c_null_ptr
+  end type fgsl_vector
+
+contains
+  function fgsl_vector_align(p_x, f_x)
+    real(fgsl_double), pointer :: p_x(:)
+    type(fgsl_vector) :: f_x
+    integer :: fgsl_vector_align
+    fgsl_vector_align = 4
+  end function fgsl_vector_align
+end module fgsl
+
+module tmod
+  use fgsl
+  implicit none
+contains
+  subroutine expb_df() bind(c)
+    type(fgsl_vector) :: f_x
+    real(fgsl_double), pointer :: p_x(:)
+    integer :: status
+    status = fgsl_vector_align(p_x, f_x)
+  end subroutine expb_df
+end module tmod
+
+! { dg-final { cleanup-modules "fgsl tmod" } } 
+
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 128389)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -2851,11 +2851,22 @@ gfc_conv_initializer (gfc_expr * expr, g
   if (!(expr || pointer))
     return NULL_TREE;
 
+  /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
+     (these are the only two iso_c_binding derived types that can be
+     used as initialization expressions).  If so, we need to modify
+     the 'expr' to be that for a (void *).  */
   if (expr != NULL && expr->ts.type == BT_DERIVED
-      && 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->ts.is_iso_c && expr->ts.derived)
+    {
+      gfc_symbol *derived = expr->ts.derived;
+
       expr = gfc_int_expr (0);
+
+      /* The derived symbol has already been converted to a (void *).  Use
+	 its kind.  */
+      expr->ts.f90_type = derived->ts.f90_type;
+      expr->ts.kind = derived->ts.kind;
+    }
   
   if (array)
     {
 


More information about the Fortran mailing list