1 #include <omp.h>
2 #include <stdlib.h>
3 
4 struct S
5 {
6   int a, b, c, d;
7 };
8 typedef struct S S;
9 
main(void)10 int main (void)
11 {
12   int d = omp_get_default_device ();
13   int id = omp_get_initial_device ();
14 
15   if (d < 0 || d >= omp_get_num_devices ())
16     d = id;
17 
18   S s;
19   #pragma omp target enter data map (alloc: s.a, s.b, s.c, s.d)
20   #pragma omp target enter data map (alloc: s.c)
21   #pragma omp target enter data map (alloc: s.b, s.d)
22   #pragma omp target enter data map (alloc: s.a, s.c, s.b)
23 
24   #pragma omp target exit data map (release: s.a)
25   #pragma omp target exit data map (release: s.d)
26   #pragma omp target exit data map (release: s.c)
27   #pragma omp target exit data map (release: s.b)
28 
29   /* OpenMP 5.0 structure element mapping rules describe that elements of same
30      structure variable should allocate/deallocate in a uniform fashion, so
31      all elements of 's' should be removed together by above 'exit data's.  */
32   if (d != id)
33     {
34       if (omp_target_is_present (&s, d))
35 	abort ();
36       if (omp_target_is_present (&s.a, d))
37 	abort ();
38       if (omp_target_is_present (&s.b, d))
39 	abort ();
40       if (omp_target_is_present (&s.c, d))
41 	abort ();
42       if (omp_target_is_present (&s.d, d))
43 	abort ();
44     }
45 
46   return 0;
47 }
48