This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gfortran, PR33254] Add -fbounds-checking for character array constructors


Tobias Burnus wrote:
Built and tested on i386-darwin. Ok?
I think the patch is ok, however: The bounds check is done
unconditionally whereas the subject implies that it is only done with
-fbounds-check.

(I'm slightly inclined to prefer to have the check with -fbounds-check
only, but I am also satisfied with an unconditional error.)

Other compilers:
a) NAG f95 and g95 always give a run-time error
b) ifort, sunf95, openf95 give no error (not even with bounds checking
enabled)

Current gfortran does (b), with the patch it does (a)

I committed the patch after conditionalizing the check on -fbounds-check. I also included the fix for PR 33727 under the obviously correct rule and amended the testcase to verify that it works. I've attached what I committed. Built and tested, of course.


Cheers,
- Tobi
2007-10-13  Tobias Schlueter  <tobi@gcc.gnu.org>
	    Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/33254
	PR fortran/33727
fortran/
	* trans-array.c (get_array_ctor_var_strlen): Check upper bound for
	constness instead of lower bound.
	(get_array_ctor_strlen): Add bounds-checking code.
testsuite/
	* bounds_check_10.f90: New.

diff -r 011bb9739b2b gcc/fortran/trans-array.c
--- a/gcc/fortran/trans-array.c	Sat Oct 13 15:03:07 2007 +0000
+++ b/gcc/fortran/trans-array.c	Sat Oct 13 23:32:58 2007 +0200
@@ -1340,7 +1340,7 @@ get_array_ctor_var_strlen (gfc_expr * ex
 
 	case REF_SUBSTRING:
 	  if (ref->u.ss.start->expr_type != EXPR_CONSTANT
-		|| ref->u.ss.start->expr_type != EXPR_CONSTANT)
+	      || ref->u.ss.end->expr_type != EXPR_CONSTANT)
 	    break;
 	  mpz_init_set_ui (char_len, 1);
 	  mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
@@ -1413,6 +1413,7 @@ get_array_ctor_strlen (stmtblock_t *bloc
 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor * c, tree * len)
 {
   bool is_const;
+  tree first_len = NULL_TREE;
   
   is_const = TRUE;
 
@@ -1446,6 +1447,23 @@ get_array_ctor_strlen (stmtblock_t *bloc
 	  is_const = false;
 	  get_array_ctor_all_strlen (block, c->expr, len);
 	  break;
+	}
+      if (flag_bounds_check)
+	{
+	  if (!first_len)
+	    first_len = *len;
+	  else
+	    {
+	      /* Verify that all constructor elements are of the same
+		 length.  */
+	      tree cond = fold_build2 (NE_EXPR, boolean_type_node,
+				       first_len, *len);
+	      gfc_trans_runtime_check
+		(cond, block, &c->expr->where,
+		 "Different CHARACTER lengths (%ld/%ld) in array constructor",
+		 fold_convert (long_integer_type_node, first_len),
+		 fold_convert (long_integer_type_node, *len));
+	    }
 	}
     }
 
diff -r 011bb9739b2b gcc/testsuite/gfortran.dg/bounds_check_10.f90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/gfortran.dg/bounds_check_10.f90	Sat Oct 13 23:32:58 2007 +0200
@@ -0,0 +1,15 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Different CHARACTER lengths" }
+! PR fortran/33254: No bounds checking for array constructors
+program array_char
+implicit none
+character (len=2) :: x, y
+character (len=2) :: z(3)
+x = "a "
+y = "cd"
+z = [y(1:1), x(1:len(trim(x)))]  ! should work
+z = [trim(x), trim(y), "aaaa"] ! [ "a", "cd", "aaaa" ] should catch first error
+end program array_char
+
+! { dg-output "Different CHARACTER lengths .1/2. in array constructor" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]