summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/trans-array.c19
-rw-r--r--gcc/fortran/trans-intrinsic.c1
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/auto_char_len_3.f9025
6 files changed, 55 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index ba6886ab084..dc1cdea6ec0 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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>
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 9f5337b093f..a865d5749d1 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -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);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 6ec0a5107be..c6a23134ed7 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -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);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index e571df9d3a9..4955fe48c49 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bf0df239038..3dff55cba19 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..b94151148af
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/auto_char_len_3.f90
@@ -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
OpenPOWER on IntegriCloud