re PR fortran/77505 (Negative character length not treated as LEN=0)
authorElizebeth Punnoose <elizebeth.punnoose@hpe.com>
Thu, 1 Dec 2016 23:11:35 +0000 (23:11 +0000)
committerSteven G. Kargl <kargl@gcc.gnu.org>
Thu, 1 Dec 2016 23:11:35 +0000 (23:11 +0000)
2016-12-01  Elizebeth Punnoose  <elizebeth.punnoose@hpe.com>

PR fortran/77505
* trans-array.c (trans_array_constructor): Treat negative character
length as LEN = 0.

2016-12-01  Elizebeth Punnoose  <elizebeth.punnoose@hpe.com>

PR fortran/77505
* gfortran.dg/char_length_20.f90: New test.
* gfortran.dg/char_length_21.f90: Ditto.

From-SVN: r243143

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

index d410392..20a9f2e 100644 (file)
@@ -1,3 +1,9 @@
+2016-12-01  Elizebeth Punnoose  <elizebeth.punnoose@hpe.com>
+
+       PR fortran/77505
+       * trans-array.c (trans_array_constructor): Treat negative character
+       length as LEN = 0.
+
 2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/78279
index 803462a..ac90a4b 100644 (file)
@@ -2226,6 +2226,8 @@ trans_array_constructor (gfc_ss * ss, locus * where)
   gfc_ss_info *ss_info;
   gfc_expr *expr;
   gfc_ss *s;
+  tree neg_len;
+  char *msg;
 
   /* Save the old values for nested checking.  */
   old_first_len = first_len;
@@ -2271,6 +2273,29 @@ trans_array_constructor (gfc_ss * ss, locus * where)
          gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
                              gfc_charlen_type_node);
          ss_info->string_length = length_se.expr;
+
+         /* Check if the character length is negative.  If it is, then
+            set LEN = 0.  */
+         neg_len = fold_build2_loc (input_location, LT_EXPR,
+                                    boolean_type_node, ss_info->string_length,
+                                    build_int_cst (gfc_charlen_type_node, 0));
+         /* Print a warning if bounds checking is enabled.  */
+         if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
+           {
+             msg = xasprintf ("Negative character length treated as LEN = 0");
+             gfc_trans_runtime_check (false, true, neg_len, &length_se.pre,
+                                      where, msg);
+             free (msg);
+           }
+
+         ss_info->string_length
+           = fold_build3_loc (input_location, COND_EXPR,
+                              gfc_charlen_type_node, neg_len,
+                              build_int_cst (gfc_charlen_type_node, 0),
+                              ss_info->string_length);
+         ss_info->string_length = gfc_evaluate_now (ss_info->string_length,
+                                                    &length_se.pre);
+
          gfc_add_block_to_block (&outer_loop->pre, &length_se.pre);
          gfc_add_block_to_block (&outer_loop->post, &length_se.post);
        }
index 321a48a..dcbdf56 100644 (file)
@@ -1,3 +1,9 @@
+2016-12-01  Elizebeth Punnoose  <elizebeth.punnoose@hpe.com>
+
+       PR fortran/77505
+       * gfortran.dg/char_length_20.f90: New test.
+       * gfortran.dg/char_length_21.f90: Ditto.
+
 2016-12-01  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/78279
diff --git a/gcc/testsuite/gfortran.dg/char_length_20.f90 b/gcc/testsuite/gfortran.dg/char_length_20.f90
new file mode 100644 (file)
index 0000000..38a19c5
--- /dev/null
@@ -0,0 +1,13 @@
+! { dg-do run }
+! { dg-options "-fcheck=bounds" }
+program rabbithole
+   implicit none
+   character(len=:), allocatable :: text_block(:)
+   integer i, ii
+   character(len=10) :: cten='abcdefghij'
+   character(len=20) :: ctwenty='abcdefghijabcdefghij'
+   ii = -6
+   text_block=[ character(len=ii) :: cten, ctwenty ]
+   if (any(len_trim(text_block) /= 0)) call abort
+end program rabbithole
+! { dg-output "At line 10 of file .*char_length_20.f90.*Fortran runtime warning: Negative character length treated as LEN = 0" }
diff --git a/gcc/testsuite/gfortran.dg/char_length_21.f90 b/gcc/testsuite/gfortran.dg/char_length_21.f90
new file mode 100644 (file)
index 0000000..76b7e8e
--- /dev/null
@@ -0,0 +1,11 @@
+! { dg-do run }
+program rabbithole
+   implicit none
+   character(len=:), allocatable :: text_block(:)
+   integer i, ii
+   character(len=10) :: cten='abcdefghij'
+   character(len=20) :: ctwenty='abcdefghijabcdefghij'
+   ii = -6
+   text_block = [character(len=ii) :: cten, ctwenty]
+   if (any(len_trim(text_block) /= 0)) call abort
+end program rabbithole