9.5. Restrictions on the atomic Construct#

The following non-conforming examples illustrate the restrictions on the atomic construct.

//%compiler: clang
//%cflags: -fopenmp

/*
* name: atomic_restrict.1
* type: C
* version: omp_3.1
*/
void atomic_wrong ()
{
 union {int n; float x;} u;

#pragma omp parallel
  {
#pragma omp atomic update
    u.n++;

#pragma omp atomic update
    u.x += 1.0;

/* Incorrect because the atomic constructs reference the same location
   through incompatible types */
  }
}
!!%compiler: gfortran
!!%cflags: -fopenmp

! name: atomic_restrict.1
! type: F-fixed
! version: omp_3.1
      SUBROUTINE ATOMIC_WRONG()
        INTEGER:: I
        REAL:: R
        EQUIVALENCE(I,R)

!$OMP   PARALLEL
!$OMP     ATOMIC UPDATE
            I = I + 1
!$OMP     ATOMIC UPDATE
            R = R + 1.0
! incorrect because I and R reference the same location
! but have different types
!$OMP   END PARALLEL
      END SUBROUTINE ATOMIC_WRONG
//%compiler: clang
//%cflags: -fopenmp

/*
* name: atomic_restrict.2
* type: C
* version: omp_3.1
*/
void atomic_wrong2 ()
{
 int  x;
 int *i;
 float   *r;

 i = &x;
 r = (float *)&x;

#pragma omp parallel
  {
#pragma omp atomic update
    *i += 1;

#pragma omp atomic update
    *r += 1.0;

/* Incorrect because the atomic constructs reference the same location
   through incompatible types */

  }
}

The following example is non-conforming because I and R reference the same location but have different types.

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: atomic_restrict.2
! type: F-fixed
! version: omp_3.1
      SUBROUTINE SUB()
        COMMON /BLK/ R
        REAL R

!$OMP   ATOMIC UPDATE
          R = R + 1.0
      END SUBROUTINE SUB

      SUBROUTINE ATOMIC_WRONG2()
        COMMON /BLK/ I
        INTEGER I

!$OMP   PARALLEL

!$OMP     ATOMIC UPDATE
            I = I + 1
          CALL SUB()
!$OMP   END PARALLEL
      END SUBROUTINE ATOMIC_WRONG2

Although the following example might work on some implementations, this is also non-conforming:

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: atomic_restrict.3
! type: F-fixed
! version: omp_3.1
      SUBROUTINE ATOMIC_WRONG3
        INTEGER:: I
        REAL:: R
        EQUIVALENCE(I,R)

!$OMP   PARALLEL
!$OMP     ATOMIC UPDATE
            I = I + 1
! incorrect because I and R reference the same location
! but have different types
!$OMP   END PARALLEL

!$OMP   PARALLEL
!$OMP     ATOMIC UPDATE
            R = R + 1.0
! incorrect because I and R reference the same location
! but have different types
!$OMP   END PARALLEL

      END SUBROUTINE ATOMIC_WRONG3