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]

[patch, libfortran] PR 34670 - intrinsics bounds checking (partial)


Hello world,

the attached patch, plus test cases, implements bounds checking
in quite a few array intrinsics.  This isn't yet complete (some
intrinsics are still missing), but the patch is fairly self-contained,
and the number of test cases is large enough that I thought this is a
logical point for a patch :-)

The number of test cases is so large because each of the codepaths
in the functions generated from ifunction.m4 and iforeach.m4 is tested
once, and a program can only fail once :-)

Thanks to Jerry for helping me with the syntax of the test cases on IRC.

	Thomas

2008-01-07  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR libfortran/34670
	* m4/iparm.m4 (upcase):  New macro (copied from the m4 manual).
	(u_name):  New macro for the upper case name of the intrinsic.
	* m4/iforeach.m4 (name`'rtype_qual`_'atype_code):  Add
	bounds checking and rank check, depending on
	compile_options.bounds_check.
	(`m'name`'rtype_qual`_'atype_code):  Likewise.
	(`s'name`'rtype_qual`_'atype_code):  Likewise.
	* m4/ifunction.m4 (name`'rtype_qual`_'atype_code):  Add
	bounds checking and rank check, depending on
	compile_options.bounds_check.
	(`m'name`'rtype_qual`_'atype_code):  Likewise.
	(`s'name`'rtype_qual`_'atype_code):  Likewise.
	* generated/all_l16.c: Regenerated.
	* generated/all_l4.c: Regenerated.
	* generated/all_l8.c: Regenerated.
	* generated/any_l16.c: Regenerated.
	* generated/any_l4.c: Regenerated.
	* generated/any_l8.c: Regenerated.
	* generated/count_16_l16.c: Regenerated.
	* generated/count_16_l4.c: Regenerated.
	* generated/count_16_l8.c: Regenerated.
	* generated/count_4_l16.c: Regenerated.
	* generated/count_4_l4.c: Regenerated.
	* generated/count_4_l8.c: Regenerated.
	* generated/count_8_l16.c: Regenerated.
	* generated/count_8_l4.c: Regenerated.
	* generated/count_8_l8.c: Regenerated.
	* generated/maxloc0_16_i1.c: Regenerated.
	* generated/maxloc0_16_i16.c: Regenerated.
	* generated/maxloc0_16_i2.c: Regenerated.
	* generated/maxloc0_16_i4.c: Regenerated.
	* generated/maxloc0_16_i8.c: Regenerated.
	* generated/maxloc0_16_r10.c: Regenerated.
	* generated/maxloc0_16_r16.c: Regenerated.
	* generated/maxloc0_16_r4.c: Regenerated.
	* generated/maxloc0_16_r8.c: Regenerated.
	* generated/maxloc0_4_i1.c: Regenerated.
	* generated/maxloc0_4_i16.c: Regenerated.
	* generated/maxloc0_4_i2.c: Regenerated.
	* generated/maxloc0_4_i4.c: Regenerated.
	* generated/maxloc0_4_i8.c: Regenerated.
	* generated/maxloc0_4_r10.c: Regenerated.
	* generated/maxloc0_4_r16.c: Regenerated.
	* generated/maxloc0_4_r4.c: Regenerated.
	* generated/maxloc0_4_r8.c: Regenerated.
	* generated/maxloc0_8_i1.c: Regenerated.
	* generated/maxloc0_8_i16.c: Regenerated.
	* generated/maxloc0_8_i2.c: Regenerated.
	* generated/maxloc0_8_i4.c: Regenerated.
	* generated/maxloc0_8_i8.c: Regenerated.
	* generated/maxloc0_8_r10.c: Regenerated.
	* generated/maxloc0_8_r16.c: Regenerated.
	* generated/maxloc0_8_r4.c: Regenerated.
	* generated/maxloc0_8_r8.c: Regenerated.
	* generated/maxloc1_16_i1.c: Regenerated.
	* generated/maxloc1_16_i16.c: Regenerated.
	* generated/maxloc1_16_i2.c: Regenerated.
	* generated/maxloc1_16_i4.c: Regenerated.
	* generated/maxloc1_16_i8.c: Regenerated.
	* generated/maxloc1_16_r10.c: Regenerated.
	* generated/maxloc1_16_r16.c: Regenerated.
	* generated/maxloc1_16_r4.c: Regenerated.
	* generated/maxloc1_16_r8.c: Regenerated.
	* generated/maxloc1_4_i1.c: Regenerated.
	* generated/maxloc1_4_i16.c: Regenerated.
	* generated/maxloc1_4_i2.c: Regenerated.
	* generated/maxloc1_4_i4.c: Regenerated.
	* generated/maxloc1_4_i8.c: Regenerated.
	* generated/maxloc1_4_r10.c: Regenerated.
	* generated/maxloc1_4_r16.c: Regenerated.
	* generated/maxloc1_4_r4.c: Regenerated.
	* generated/maxloc1_4_r8.c: Regenerated.
	* generated/maxloc1_8_i1.c: Regenerated.
	* generated/maxloc1_8_i16.c: Regenerated.
	* generated/maxloc1_8_i2.c: Regenerated.
	* generated/maxloc1_8_i4.c: Regenerated.
	* generated/maxloc1_8_i8.c: Regenerated.
	* generated/maxloc1_8_r10.c: Regenerated.
	* generated/maxloc1_8_r16.c: Regenerated.
	* generated/maxloc1_8_r4.c: Regenerated.
	* generated/maxloc1_8_r8.c: Regenerated.
	* generated/maxval_i1.c: Regenerated.
	* generated/maxval_i16.c: Regenerated.
	* generated/maxval_i2.c: Regenerated.
	* generated/maxval_i4.c: Regenerated.
	* generated/maxval_i8.c: Regenerated.
	* generated/maxval_r10.c: Regenerated.
	* generated/maxval_r16.c: Regenerated.
	* generated/maxval_r4.c: Regenerated.
	* generated/maxval_r8.c: Regenerated.
	* generated/minloc0_16_i1.c: Regenerated.
	* generated/minloc0_16_i16.c: Regenerated.
	* generated/minloc0_16_i2.c: Regenerated.
	* generated/minloc0_16_i4.c: Regenerated.
	* generated/minloc0_16_i8.c: Regenerated.
	* generated/minloc0_16_r10.c: Regenerated.
	* generated/minloc0_16_r16.c: Regenerated.
	* generated/minloc0_16_r4.c: Regenerated.
	* generated/minloc0_16_r8.c: Regenerated.
	* generated/minloc0_4_i1.c: Regenerated.
	* generated/minloc0_4_i16.c: Regenerated.
	* generated/minloc0_4_i2.c: Regenerated.
	* generated/minloc0_4_i4.c: Regenerated.
	* generated/minloc0_4_i8.c: Regenerated.
	* generated/minloc0_4_r10.c: Regenerated.
	* generated/minloc0_4_r16.c: Regenerated.
	* generated/minloc0_4_r4.c: Regenerated.
	* generated/minloc0_4_r8.c: Regenerated.
	* generated/minloc0_8_i1.c: Regenerated.
	* generated/minloc0_8_i16.c: Regenerated.
	* generated/minloc0_8_i2.c: Regenerated.
	* generated/minloc0_8_i4.c: Regenerated.
	* generated/minloc0_8_i8.c: Regenerated.
	* generated/minloc0_8_r10.c: Regenerated.
	* generated/minloc0_8_r16.c: Regenerated.
	* generated/minloc0_8_r4.c: Regenerated.
	* generated/minloc0_8_r8.c: Regenerated.
	* generated/minloc1_16_i1.c: Regenerated.
	* generated/minloc1_16_i16.c: Regenerated.
	* generated/minloc1_16_i2.c: Regenerated.
	* generated/minloc1_16_i4.c: Regenerated.
	* generated/minloc1_16_i8.c: Regenerated.
	* generated/minloc1_16_r10.c: Regenerated.
	* generated/minloc1_16_r16.c: Regenerated.
	* generated/minloc1_16_r4.c: Regenerated.
	* generated/minloc1_16_r8.c: Regenerated.
	* generated/minloc1_4_i1.c: Regenerated.
	* generated/minloc1_4_i16.c: Regenerated.
	* generated/minloc1_4_i2.c: Regenerated.
	* generated/minloc1_4_i4.c: Regenerated.
	* generated/minloc1_4_i8.c: Regenerated.
	* generated/minloc1_4_r10.c: Regenerated.
	* generated/minloc1_4_r16.c: Regenerated.
	* generated/minloc1_4_r4.c: Regenerated.
	* generated/minloc1_4_r8.c: Regenerated.
	* generated/minloc1_8_i1.c: Regenerated.
	* generated/minloc1_8_i16.c: Regenerated.
	* generated/minloc1_8_i2.c: Regenerated.
	* generated/minloc1_8_i4.c: Regenerated.
	* generated/minloc1_8_i8.c: Regenerated.
	* generated/minloc1_8_r10.c: Regenerated.
	* generated/minloc1_8_r16.c: Regenerated.
	* generated/minloc1_8_r4.c: Regenerated.
	* generated/minloc1_8_r8.c: Regenerated.
	* generated/minval_i1.c: Regenerated.
	* generated/minval_i16.c: Regenerated.
	* generated/minval_i2.c: Regenerated.
	* generated/minval_i4.c: Regenerated.
	* generated/minval_i8.c: Regenerated.
	* generated/minval_r10.c: Regenerated.
	* generated/minval_r16.c: Regenerated.
	* generated/minval_r4.c: Regenerated.
	* generated/minval_r8.c: Regenerated.
	* generated/product_c10.c: Regenerated.
	* generated/product_c16.c: Regenerated.
	* generated/product_c4.c: Regenerated.
	* generated/product_c8.c: Regenerated.
	* generated/product_i1.c: Regenerated.
	* generated/product_i16.c: Regenerated.
	* generated/product_i2.c: Regenerated.
	* generated/product_i4.c: Regenerated.
	* generated/product_i8.c: Regenerated.
	* generated/product_r10.c: Regenerated.
	* generated/product_r16.c: Regenerated.
	* generated/product_r4.c: Regenerated.
	* generated/product_r8.c: Regenerated.
	* generated/sum_c10.c: Regenerated.
	* generated/sum_c16.c: Regenerated.
	* generated/sum_c4.c: Regenerated.
	* generated/sum_c8.c: Regenerated.
	* generated/sum_i1.c: Regenerated.
	* generated/sum_i16.c: Regenerated.
	* generated/sum_i2.c: Regenerated.
	* generated/sum_i4.c: Regenerated.
	* generated/sum_i8.c: Regenerated.
	* generated/sum_r10.c: Regenerated.
	* generated/sum_r16.c: Regenerated.
	* generated/sum_r4.c: Regenerated.
	* generated/sum_r8.c: Regenerated.

2008-01-07  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR libfortran/34670
	* all_bounds_1.f90: New test case.
	* maxloc_bounds_1.f90: New test case.
	* maxloc_bounds_2.f90: New test case.
	* maxloc_bounds_3.f90: New test case.
	* maxloc_bounds_4.f90: New test case.
	* maxloc_bounds_5.f90: New test case.
	* maxloc_bounds_6.f90: New test case.
	* maxloc_bounds_7.f90: New test case.
	* maxloc_bounds_8.f90: New test case.
Index: m4/iforeach.m4
===================================================================
--- m4/iforeach.m4	(revision 131305)
+++ m4/iforeach.m4	(working copy)
@@ -36,11 +36,22 @@ name`'rtype_qual`_'atype_code (rtype * c
     }
   else
     {
-      if (GFC_DESCRIPTOR_RANK (retarray) != 1)
-	runtime_error ("rank of return array does not equal 1");
+      if (compile_options.bounds_check)
+	{
+	  int ret_rank;
+	  index_type ret_extent;
 
-      if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
-        runtime_error ("dimension of return array incorrect");
+	  ret_rank = GFC_DESCRIPTOR_RANK (retarray);
+	  if (ret_rank != 1)
+	    runtime_error ("rank of return array in u_name intrinsic"
+			   " should be 1, is %d", ret_rank);
+
+	  ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+	  if (ret_extent != rank)
+	    runtime_error ("Incorrect extent in return value of"
+			   " u_name intrnisic: is %ld, should be %d",
+			   (long int) ret_extent, rank);
+	}
     }
 
   dstride = retarray->dim[0].stride;
@@ -141,11 +152,40 @@ void
     }
   else
     {
-      if (GFC_DESCRIPTOR_RANK (retarray) != 1)
-	runtime_error ("rank of return array does not equal 1");
-
-      if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
-        runtime_error ("dimension of return array incorrect");
+      if (compile_options.bounds_check)
+	{
+	  int ret_rank, mask_rank;
+	  index_type ret_extent;
+	  int n;
+	  index_type array_extent, mask_extent;
+
+	  ret_rank = GFC_DESCRIPTOR_RANK (retarray);
+	  if (ret_rank != 1)
+	    runtime_error ("rank of return array in u_name intrinsic"
+			   " should be 1, is %d", ret_rank);
+
+	  ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+	  if (ret_extent != rank)
+	    runtime_error ("Incorrect extent in return value of"
+			   " u_name intrnisic: is %ld, should be %d",
+			   (long int) ret_extent, rank);
+	
+	  mask_rank = GFC_DESCRIPTOR_RANK (mask);
+	  if (rank != mask_rank)
+	    runtime_error ("rank of MASK argument in u_name intrnisic"
+	                   "should be %d, is %d", rank, mask_rank);
+
+	  for (n=0; n<rank; n++)
+	    {
+	      array_extent = array->dim[n].ubound + 1 - array->dim[n].lbound;
+	      mask_extent = mask->dim[n].ubound + 1 - mask->dim[n].lbound;
+	      if (array_extent != mask_extent)
+		runtime_error ("Incorrect extent in MASK argument of"
+			       " u_name intrinsic in dimension %d:"
+			       " is %ld, should be %ld", n + 1,
+			       (long int) mask_extent, (long int) array_extent);
+	    }
+	}
     }
 
   mask_kind = GFC_DESCRIPTOR_SIZE (mask);
@@ -270,11 +310,20 @@ void
     }
   else
     {
-      if (GFC_DESCRIPTOR_RANK (retarray) != 1)
-	runtime_error ("rank of return array does not equal 1");
+      if (compile_options.bounds_check)
+	{
+	  int ret_rank;
+	  index_type ret_extent;
 
-      if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
-        runtime_error ("dimension of return array incorrect");
+	  ret_rank = GFC_DESCRIPTOR_RANK (retarray);
+	  if (ret_rank != 1)
+	    runtime_error ("rank of return array in u_name intrinsic"
+			   " should be 1, is %d", ret_rank);
+
+	  ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+	    if (ret_extent != rank)
+	      runtime_error ("dimension of return array incorrect");
+	}
     }
 
   dstride = retarray->dim[0].stride;
Index: m4/iparm.m4
===================================================================
--- m4/iparm.m4	(revision 131305)
+++ m4/iparm.m4	(working copy)
@@ -30,4 +30,6 @@ define(rtype_qual,`_'rtype_kind)dnl
 define(atype_max, atype_name`_HUGE')dnl
 define(atype_min,ifelse(regexp(file, `_\(.\)[0-9]*\.c$', `\1'),`i',`(-'atype_max`-1)',`-'atype_max))dnl
 define(name, regexp(regexp(file, `[^/]*$', `\&'), `^\([^_]*\)_', `\1'))dnl
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`u_name',`regexp(upcase(name),`\([A-Z]*\)',`\1')')dnl
 define(rtype_ccode,ifelse(rtype_letter,`i',rtype_kind,rtype_code))dnl
Index: m4/ifunction.m4
===================================================================
--- m4/ifunction.m4	(revision 131305)
+++ m4/ifunction.m4	(working copy)
@@ -98,7 +98,25 @@ name`'rtype_qual`_'atype_code (rtype * c
   else
     {
       if (rank != GFC_DESCRIPTOR_RANK (retarray))
-	runtime_error ("rank of return array incorrect");
+	runtime_error ("rank of return array incorrect in"
+		       " u_name intrinsic: is %d, should be %d",
+		       GFC_DESCRIPTOR_RANK (retarray), rank);
+
+      if (compile_options.bounds_check)
+	{
+	  for (n=0; n < rank; n++)
+	    {
+	      index_type ret_extent;
+
+	      ret_extent = retarray->dim[n].ubound + 1
+		- retarray->dim[n].lbound;
+	      if (extent[n] != ret_extent)
+		runtime_error ("Incorrect extent in return value of"
+			       " u_name intrinsic in dimension %d:"
+			       " is %ld, should be %ld", n + 1,
+			       (long int) ret_extent, (long int) extent[n]);
+	    }
+	}
     }
 
   for (n = 0; n < rank; n++)
@@ -269,7 +287,35 @@ void
   else
     {
       if (rank != GFC_DESCRIPTOR_RANK (retarray))
-	runtime_error ("rank of return array incorrect");
+	runtime_error ("rank of return array incorrect in u_name intrinsic");
+
+      if (compile_options.bounds_check)
+	{
+	  for (n=0; n < rank; n++)
+	    {
+	      index_type ret_extent;
+
+	      ret_extent = retarray->dim[n].ubound + 1
+		- retarray->dim[n].lbound;
+	      if (extent[n] != ret_extent)
+		runtime_error ("Incorrect extent in return value of"
+			       " u_name intrinsic in dimension %d:"
+			       " is %ld, should be %ld", n + 1,
+			       (long int) ret_extent, (long int) extent[n]);
+	    }
+          for (n=0; n<= rank; n++)
+            {
+              index_type mask_extent, array_extent;
+
+	      array_extent = array->dim[n].ubound + 1 - array->dim[n].lbound;
+	      mask_extent = mask->dim[n].ubound + 1 - mask->dim[n].lbound;
+	      if (array_extent != mask_extent)
+		runtime_error ("Incorrect extent in MASK argument of"
+			       " u_name intrinsic in dimension %d:"
+			       " is %ld, should be %ld", n + 1,
+			       (long int) mask_extent, (long int) array_extent);
+	    }
+	}
     }
 
   for (n = 0; n < rank; n++)
@@ -376,13 +422,21 @@ void
     }
   else
     {
-      if (GFC_DESCRIPTOR_RANK (retarray) != 1)
-	runtime_error ("rank of return array does not equal 1");
+      if (compile_options.bounds_check)
+	{
+	  int ret_rank;
+	  index_type ret_extent;
 
-      if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
-        runtime_error ("dimension of return array incorrect");
+	  ret_rank = GFC_DESCRIPTOR_RANK (retarray);
+	  if (ret_rank != 1)
+	    runtime_error ("rank of return array in u_name intrinsic"
+			   " should be 1, is %d", ret_rank);
+
+	  ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+	    if (ret_extent != rank)
+	      runtime_error ("dimension of return array incorrect");
+	}
     }
-
     dstride = retarray->dim[0].stride;
     dest = retarray->data;
 
! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }
program main
  integer(kind=4), allocatable :: f(:,:)
  integer(kind=4) :: res(3)
  character(len=80) line
  allocate (f(2,2))
  f = 3
  res = maxloc(f,dim=1)
  write(line,fmt='(80I1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }

! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }
program main
  integer(kind=4), allocatable :: f(:,:)
  logical, allocatable :: m(:,:)
  integer(kind=4) :: res(3)
  character(len=80) line
  allocate (f(2,2),m(2,2))
  f = 3
  m = .true.
  res = maxloc(f,dim=1,mask=m)
  write(line,fmt='(80I1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }

! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in MASK argument of MAXLOC intrinsic in dimension 2: is 3, should be 2" }
program main
  integer(kind=4), allocatable :: f(:,:)
  logical, allocatable :: m(:,:)
  integer(kind=4) :: res(2)
  character(len=80) line
  allocate (f(2,2),m(2,3))
  f = 3
  m = .true.
  res = maxloc(f,dim=1,mask=m)
  write(line,fmt='(80I1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in MASK argument of MAXLOC intrinsic in dimension 2: is 3, should be 2" }

! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
module tst
contains
  subroutine foo(res)
    integer(kind=4), allocatable :: f(:,:)
    integer, dimension(:) :: res
    allocate (f(2,5))
    f = 3
    res = maxloc(f)
  end subroutine foo

end module tst
program main
  use tst
  implicit none
  integer(kind=4) :: res(3)
  call foo(res)
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
! { dg-final { cleanup-modules "tst" } }

! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
module tst
contains
  subroutine foo(res)
    integer(kind=4), allocatable :: f(:,:)
    integer, dimension(:) :: res
    allocate (f(2,5))
    f = 3
    res = maxloc(f,mask=f>2)
  end subroutine foo

end module tst
program main
  use tst
  implicit none
  integer(kind=4) :: res(3)
  call foo(res)
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
! { dg-final { cleanup-modules "tst" } }
! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in MASK argument of MAXLOC intrinsic in dimension 2: is 3, should be 2" }
program main
  integer(kind=4), allocatable :: f(:,:)
  logical, allocatable :: m(:,:)
  integer(kind=4) :: res(2)
  character(len=80) line
  allocate (f(2,2),m(2,3))
  f = 3
  m = .true.
  res = maxloc(f,mask=m)
  write(line,fmt='(80I1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in MASK argument of MAXLOC intrinsic in dimension 2: is 3, should be 2" }
! { dg-final { cleanup-modules "tst" } }
! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
module tst
contains
  subroutine foo(res)
    integer(kind=4), allocatable :: f(:,:)
    integer, dimension(:) :: res
    allocate (f(2,5))
    f = 3
    res = maxloc(f,mask=.true.)
  end subroutine foo

end module tst
program main
  use tst
  implicit none
  integer(kind=4) :: res(3)
  call foo(res)
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrnisic: is 3, should be 2" }
! { dg-final { cleanup-modules "tst" } }
! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }
program main
  integer(kind=4), allocatable :: f(:,:)
  logical, allocatable :: m(:,:)
  integer(kind=4) :: res(3)
  character(len=80) line
  allocate (f(2,2),m(2,2))
  f = 3
  m = .true.
  res = maxloc(f,dim=1,mask=.true.)
  write(line,fmt='(80I1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of MAXLOC intrinsic in dimension 1: is 3, should be 2" }

! { dg-do run }
! { dg-options "-fbounds-check" }
! { dg-shouldfail "Incorrect extent in return value of ALL intrinsic" }
program main
  logical(kind=4), allocatable :: f(:,:)
  logical(kind=4) :: res(3)
  character(len=80) line
  allocate (f(2,2))
  f = .false.
  f(1,1) = .true.
  f(2,1) = .true.
  res = all(f,dim=1)
  write(line,fmt='(80L1)') res
end program main
! { dg-output "Fortran runtime error: Incorrect extent in return value of ALL intrinsic in dimension 1: is 3, should be 2" }



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