Contiguity Checking for Pointer Assignments in the Intel® Fortran Compiler

ID 659222
Updated 10/17/2018
Version Latest



The Fortran 2008 Standard introduced the CONTIGUOUS attribute for assumed shape arrays and pointers. The CONTIGUOUS attribute may help the compiler optimize more effectively, see /content/www/us/en/develop/articles/vectorization-and-array-contiguity.html. However, specifying the CONTIGUOUS attribute for an assumed shape array or pointer that may not be contiguous can lead to incorrect behavior at run-time. First introduced in the Intel® Fortran Compiler version 18, the compiler option, -check contiguous, allows an application to check at run-time whether the targets of contiguous pointer assignments are indeed contiguous.

Consider the following example:

module mymod         !  source file inc.F90
  subroutine inc(b)
    real, dimension(:),             pointer :: b
#ifdef CONTIG    
    real, dimension(:), contiguous, pointer :: c
    real, dimension(:),             pointer :: c

    c => b
    c =  1.
  end subroutine inc
end module mymod

program drive_inc     ! source file drive_inc.F90
  use mymod
  implicit none
  integer, parameter          :: n=25, stride=5
  real, target,  dimension(n) :: a=0.
  real, pointer, dimension(:) :: b
  b => a(:n:stride)
  call inc(b)

  print '(5F5.0)', a
end program drive_inc

Without the contiguity attribute, results are correct.

$ ifort inc.F90 drive_inc.F90; ./a.out
   1.   0.   0.   0.   0.
   1.   0.   0.   0.   0.
   1.   0.   0.   0.   0.
   1.   0.   0.   0.   0.
   1.   0.   0.   0.   0.

Here, pointer c is declared as contiguous, but the actual target is not, leading to incorrect results.

$ ifort -DCONTIG inc.F90 drive_inc.F90; ./a.out
   1.   1.   1.   1.   1.
   0.   0.   0.   0.   0.
   0.   0.   0.   0.   0.
   0.   0.   0.   0.   0.
   0.   0.   0.   0.   0.

With the new option -check contiguous (Linux* or macOS*) or /check:contiguous (Windows*), the compiler adds run-time tests for the assignment of a contiguous pointer to a non-contiguous target. The option -traceback (/traceback) identifies the function and source file line number at which the incorrect assignment took place. It is not necessary to compile with the debugging option -g (Linux or macOS) or /Zi (Windows) in order to get this traceback.

$ ifort -DCONTIG -check contiguous -traceback inc.F90 drive_inc.F90; ./a.out
forrtl: severe (408): fort: (32): A pointer with the CONTIGUOUS attributes is being made to a non-contiguous target.

Image          PC                Routine            Line     Source
a.out         0000000000405220   Unknown            Unknown  Unknown
a.out         0000000000402AEF   mymod_mp_inc_       11      inc.F90
a.out         0000000000402C23   MAIN__               9      drive_inc.F90
a.out         0000000000402A9E   Unknown            Unknown  Unknown  00007F1A0A6B0B35   __libc_start_main  Unknown  Unknown
a.out         00000000004029A9   Unknown            Unknown  Unknown