re PR fortran/30611 ([4.1 only] Confusing error message for negative ncopies in REPEAT)
authorFrancois-Xavier Coudert <coudert@clipper.ens.fr>
Sun, 4 Feb 2007 21:33:10 +0000 (22:33 +0100)
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Sun, 4 Feb 2007 21:33:10 +0000 (21:33 +0000)
PR fortran/30611

* trans-intrinsic.c (gfc_conv_intrinsic_repeat): Evaluate
arguments only once. Generate check that NCOPIES argument is not
negative.

* intrinsics/string_intrinsics.c (string_repeat): Don't check
if ncopies is negative.

* gcc/testsuite/gfortran.dg/repeat_1.f90: New test.

From-SVN: r121581

gcc/fortran/ChangeLog
gcc/fortran/trans-intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/repeat_1.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/intrinsics/string_intrinsics.c

index 91140a76d82726f66514aa85cd10d0fe1fce5409..a78ca2ac127d783f1d80d61ad6487e1c52c321fb 100644 (file)
@@ -1,3 +1,10 @@
+2007-02-04  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       PR fortran/30611
+       * trans-intrinsic.c (gfc_conv_intrinsic_repeat): Evaluate
+       arguments only once. Generate check that NCOPIES argument is not
+       negative.
+
 2007-02-04  Steven G. Kargl <kargl@gcc.gnu.org>
 
        * fortran/invoke.texi: Update documentation.
index 6c321f1c60939d18caa8de275e8aea5ac4ab59e4..aa8008bec80cf28667f429bffe675dfeccfdfba9 100644 (file)
@@ -3357,18 +3357,32 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
   tree ncopies;
   tree var;
   tree type;
+  tree cond;
 
   args = gfc_conv_intrinsic_function_args (se, expr);
   len = TREE_VALUE (args);
   tmp = gfc_advance_chain (args, 2);
   ncopies = TREE_VALUE (tmp);
+
+  /* Check that ncopies is not negative.  */
+  ncopies = gfc_evaluate_now (ncopies, &se->pre);
+  cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
+                     build_int_cst (TREE_TYPE (ncopies), 0));
+  gfc_trans_runtime_check (cond,
+                          "Argument NCOPIES of REPEAT intrinsic is negative",
+                          &se->pre, &expr->where);
+
+  /* Compute the destination length.  */
   len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
   type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
   var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
 
+  /* Create the argument list and generate the function call.  */
   arglist = NULL_TREE;
   arglist = gfc_chainon_list (arglist, var);
-  arglist = chainon (arglist, args);
+  arglist = gfc_chainon_list (arglist, TREE_VALUE (args));
+  arglist = gfc_chainon_list (arglist, TREE_VALUE (TREE_CHAIN (args)));
+  arglist = gfc_chainon_list (arglist, ncopies);
   tmp = build_function_call_expr (gfor_fndecl_string_repeat, arglist);
   gfc_add_expr_to_block (&se->pre, tmp);
 
index 40db44b38922ba7762884e27d673149e97c6869d..da8fdb061233295bdc3f273d843b5db25528976c 100644 (file)
@@ -1,3 +1,8 @@
+2007-02-04  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       PR fortran/30611
+       * gcc/testsuite/gfortran.dg/repeat_1.f90: New test.
+
 2007-02-04  Steven G. Kargl <kargl@gcc.gnu.org>
 
        * gfortran.dg/spread_shape_1.f90: Remove tabs.
diff --git a/gcc/testsuite/gfortran.dg/repeat_1.f90 b/gcc/testsuite/gfortran.dg/repeat_1.f90
new file mode 100644 (file)
index 0000000..7a1d6f9
--- /dev/null
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-shouldfail "negative NCOPIES argument to REPEAT intrinsic" }
+  character(len=80) :: str
+  integer :: i
+  i = -1
+  write(str,"(a)") repeat ("a", f())
+  if (trim(str) /= "aaaa") call abort
+  write(str,"(a)") repeat ("a", i)
+
+contains
+
+  integer function f()
+    integer :: x = 5
+    save x
+
+    x = x - 1
+    f = x
+  end function f
+end
+! { dg-output "Fortran runtime error: Argument NCOPIES of REPEAT intrinsic is negative .* line 6)"
index 48b7e94087945974a172007d32b69ec3f1780e80..428d49a4d377f5cd91bdde19575f3c1e332c465a 100644 (file)
@@ -1,3 +1,9 @@
+2007-02-04  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       PR fortran/30611
+       * intrinsics/string_intrinsics.c (string_repeat): Don't check
+       if ncopies is negative.
+
 2007-02-04  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
        PR libfortran/30007
index e432987dcad049ef15f5df099138d1bbbb70de74..86ef9d42604abe7ff0c887c4940b28556c84258c 100644 (file)
@@ -362,14 +362,8 @@ string_repeat (char * dest, GFC_INTEGER_4 slen,
 {
   int i;
 
-  /* See if ncopies is valid.  */
-  if (ncopies < 0)
-    {
-      /* The error is already reported.  */
-      runtime_error ("Augument NCOPIES is negative.");
-    }
-
-  /* Copy characters.  */
+  /* We don't need to check that ncopies is non-negative here, because
+     the front-end already generates code for that check.  */
   for (i = 0; i < ncopies; i++) 
     {
       memmove (dest + (i * slen), src, slen);