OSDN Git Service

2006-03-09 Paul Thomas <pault@gcc.gnu.org>
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Mar 2006 05:52:06 +0000 (05:52 +0000)
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Mar 2006 05:52:06 +0000 (05:52 +0000)
PR fortran/26257
* trans-array.c (gfc_conv_expr_descriptor): Exclude calculation of
the offset and data when se->data_not_needed is set.
* trans.h: Include the data_not_need bit in gfc_se.
* trans-intrinsic.c (gfc_conv_intrinsic_size): Set it for SIZE.

2006-03-09 Paul Thomas <pault@gcc.gnu.org>

* PR fortran/26257
gfortran.dg/auto_char_len_3.f90: New test

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111860 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/fortran/trans-intrinsic.c
gcc/fortran/trans.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/auto_char_len_3.f90 [new file with mode: 0644]

index ba6886a..dc1cdea 100644 (file)
@@ -1,3 +1,11 @@
+2006-03-09 Paul Thomas <pault@gcc.gnu.org>
+
+       PR fortran/26257
+       * trans-array.c (gfc_conv_expr_descriptor): Exclude calculation of
+       the offset and data when se->data_not_needed is set.
+       * trans.h: Include the data_not_need bit in gfc_se.
+       * trans-intrinsic.c (gfc_conv_intrinsic_size): Set it for SIZE.
+
 2006-03-06  Paul Thomas  <pault@gcc.gnu.org>
             Erik Edelmann  <eedelman@gcc.gnu.org>
 
index 9f5337b..a865d57 100644 (file)
@@ -4172,14 +4172,19 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
          dim++;
        }
 
-      /* Point the data pointer at the first element in the section.  */
-      tmp = gfc_conv_array_data (desc);
-      tmp = build_fold_indirect_ref (tmp);
-      tmp = gfc_build_array_ref (tmp, offset);
-      offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
-      gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
+      if (se->data_not_needed)
+       gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
+      else
+       {
+         /* Point the data pointer at the first element in the section.  */
+         tmp = gfc_conv_array_data (desc);
+         tmp = build_fold_indirect_ref (tmp);
+         tmp = gfc_build_array_ref (tmp, offset);
+         offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
+         gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
+       }
 
-      if (se->direct_byref)
+      if (se->direct_byref && !se->data_not_needed)
        {
          /* Set the offset.  */
          tmp = gfc_conv_descriptor_offset (parm);
index 6ec0a51..c6a2313 100644 (file)
@@ -2405,6 +2405,7 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
   ss = gfc_walk_expr (actual->expr);
   gcc_assert (ss != gfc_ss_terminator);
   argse.want_pointer = 1;
+  argse.data_not_needed = 1;
   gfc_conv_expr_descriptor (&argse, actual->expr, ss);
   gfc_add_block_to_block (&se->pre, &argse.pre);
   gfc_add_block_to_block (&se->post, &argse.post);
index e571df9..4955fe4 100644 (file)
@@ -67,6 +67,10 @@ typedef struct gfc_se
   /* Ignore absent optional arguments.  Used for some intrinsics.  */
   unsigned ignore_optional:1;
 
+  /* When this is set the data and offset fields of the returned descriptor
+     are NULL.  Used by intrinsic size.  */
+  unsigned data_not_needed:1;
+
   /* Scalarization parameters.  */
   struct gfc_se *parent;
   struct gfc_ss *ss;
index bf0df23..3dff55c 100644 (file)
@@ -1,3 +1,8 @@
+2006-03-09 Paul Thomas <pault@gcc.gnu.org>
+
+       * PR fortran/26257
+       gfortran.dg/auto_char_len_3.f90: New test
+
 2006-03-08  Jeff Law  <law@redhat.com>
 
        * gcc.dg/tree-ssa/20030730-1.c: No longer expected to fail.
diff --git a/gcc/testsuite/gfortran.dg/auto_char_len_3.f90 b/gcc/testsuite/gfortran.dg/auto_char_len_3.f90
new file mode 100644 (file)
index 0000000..b941511
--- /dev/null
@@ -0,0 +1,25 @@
+! { dg-do run }
+! Test the fix for PR26257, in which the implicit reference to
+! chararray in the main program call of chararray2string would
+! cause a segfault in gfc_build_addr_expr.
+!
+! Based on the reduced testcase in the PR.
+module chtest
+contains
+  function chararray2string(chararray) result(text)
+    character(len=1), dimension(:) :: chararray    ! input
+    character(len=size(chararray, 1)) :: text      ! output
+    do i = 1,size(chararray,1)
+      text(i:i) = chararray (i)
+    end do
+  end function chararray2string
+end module chtest
+program TestStringTools
+  use chtest
+  character(len=52)               :: txt
+  character(len=1), dimension(52) :: chararr = &
+        (/(char(i+64),char(i+96), i = 1,26)/)
+  txt = chararray2string(chararr)
+  if (txt .ne. "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz") &
+        call abort ()
+end program TestStringTools