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) clause. Specific attributes should then be assigned to each variable with 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) 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 by compiler implementation and often result in data races. These races cause non-deterministic behavior, incorrect calculation results, and difficult-to-debug runtime errors.

RecommendationSeverityLikelihoodDetectableRepairablePriorityLevel
CON01-FMediumProbableYesYesP12L1

Attachments: