summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/trans-array.c2
-rw-r--r--gcc/fortran/trans-intrinsic.c7
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/char_cons_len.f9017
6 files changed, 41 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 31fcc5a8afe..cd09edaf696 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,11 @@
+2006-05-07 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/24813
+ * trans-array.c (get_array_ctor_strlen): Remove static attribute.
+ * trans.h: Add prototype for get_array_ctor_strlen.
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Switch on EXPR_ARRAY
+ and call get_array_ctor_strlen.
+
2006-05-05 Steven G. Kargl <kargls@comcast.net>
* invoke.texi: Update description of -fall-intrinsics
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index a5042eadaf1..a620bff67f0 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1328,7 +1328,7 @@ get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
/* Figure out the string length of a character array constructor.
Returns TRUE if all elements are character constants. */
-static bool
+bool
get_array_ctor_strlen (gfc_constructor * c, tree * len)
{
bool is_const;
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 1abc79aa69b..eb5286e7a6a 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -2258,6 +2258,13 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
len = build_int_cst (NULL_TREE, arg->value.character.length);
break;
+ case EXPR_ARRAY:
+ /* Obtain the string length from the function used by
+ trans-array.c(gfc_trans_array_constructor). */
+ len = NULL_TREE;
+ get_array_ctor_strlen (arg->value.constructor, &len);
+ break;
+
default:
if (arg->expr_type == EXPR_VARIABLE
&& (arg->ref == NULL || (arg->ref->next == NULL
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 0b1514e94d6..78a5d156103 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -419,6 +419,9 @@ void gfc_get_backend_locus (locus *);
extern GTY(()) tree gfc_static_ctors;
void gfc_generate_constructors (void);
+/* Get the string length of an array constructor. */
+bool get_array_ctor_strlen (gfc_constructor *, tree *);
+
/* Generate a runtime error check. */
void gfc_trans_runtime_check (tree, tree, stmtblock_t *);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 63e386943b2..d289aee418a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-07 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/24813
+ * gfortran.dg/char_cons_len_1.f90: New test.
+
2006-05-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/27427
diff --git a/gcc/testsuite/gfortran.dg/char_cons_len.f90 b/gcc/testsuite/gfortran.dg/char_cons_len.f90
new file mode 100644
index 00000000000..e50d7532d93
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char_cons_len.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! Tests the fix for PR24813 in which a character array
+! constructor, as an argument for LEN, would cause an ICE.
+!
+ character(11) :: chr1, chr2
+ i = len ((/chr1, chr2, "ggg"/))
+ j = len ((/"abcdefghijk", chr1, chr2/))
+ k = len ((/'hello ','goodbye'/))
+ l = foo ("yes siree, Bob")
+ if (any ((/11,11,7,14/) /= (/i,j,k,l/))) call abort ()
+contains
+ integer function foo (arg)
+ character(*) :: arg
+ character(len(arg)) :: ctor
+ foo = len ((/ctor/))
+ end function foo
+end