Skip to main content
GitHub

CON01-F. Explicitly declare OpenMP data-sharing attributes for all variables

All variables used within an OpenMP parallel region should have their data-sharing attributes explicitly declared, using the default(none) OpenMP clause. Specific attributes should then be assigned to each variable with OpenMP clauses such as shared , private , firstprivate , or reduction .

In Fortran, any variable used within a parallel region that lacks an explicitly declared data-sharing attribute will receive a default attribute from the compiler. If a variable intended to be private per thread is instead implicitly shared, multiple threads may modify it concurrently, leading to non-deterministic results and race conditions.

Noncompliant Code Example

In this noncompliant example, the variable temp is used to hold an intermediate calculation. The programmer has not specified a default clause. In many OpenMP implementations, scalar variables declared outside the parallel region default to shared. Consequently, all threads race to read and write to the same memory location for temp, leading to incorrect values in result.

Non-compliant code
subroutine parallel_square(n, input_arr, result_arr)
  implicit none
  integer, intent(in)  :: n
  integer, intent(in)  :: input_arr(n)
  integer, intent(out) :: result_arr(n)
  integer              :: i, temp        ! 'temp' is declared in the host scope

  ! Noncompliant: 'temp' is implicitly shared.
  ! Race condition occurs when multiple threads write to 'temp'
  !$omp parallel do
  do i = 1, n
    temp = input_arr(i) * input_arr(i)
    result_arr(i) = temp
  end do
  !$omp end parallel do

end subroutine parallel_square

Compliant Solution

In this compliant solution, the default(none) OpenMP clause is applied. This forces the compiler to verify that every variable appearing in the block has a data-sharing attribute. The variable temp is explicitly declared private, ensuring each thread has its own local instance. The arrays and size n are explicitly declared shared.

Compliant code
subroutine parallel_square(n, input_arr, result_arr)
  implicit none
  integer, intent(in)  :: n
  integer, intent(in)  :: input_arr(n)
  integer, intent(out) :: result_arr(n)
  integer              :: i, temp ! 'temp' is declared in the host scope

  ! Compliant: default(none) forces explicit declaration.
  !$omp parallel do default(none) &
  !$omp shared(n, input_arr, result_arr) &
  !$omp private(i, temp)
  do i = 1, n
    temp = input_arr(i) * input_arr(i)
    result_arr(i) = temp
  end do
  !$omp end parallel do

end subroutine parallel_square

Risk Assessment

Failure to explicitly declare data-sharing attributes leads to default behaviors that vary across compiler implementations and often result in data races. These data races cause non-deterministic behavior, incorrect calculation results, and difficult-to-debug runtime errors.

RuleSeverityLikelihoodDetectableRepairablePriorityLevel
CON01-FMediumLikelyYesYesP12L1

Attachments: