1 /* { dg-additional-options "-O0" } */
2 /* Disable optimization to ensure that the compiler does not exploit that
3 S::r + t will never be NULL due to int (&r) and (&t). */
6 extern "C" void abort ();
7 struct S { char a[64]; int (&r)[2]; char b[64]; };
9 __attribute__((noinline, noclone)) void
10 foo (S s, int (&t)[3], int z)
13 // Test that implicit mapping of reference to array does NOT
14 // behave like zero length array sections. s.r can't be used
15 // implicitly, as that means implicit mapping of the whole s
16 // and trying to dereference the references in there is unspecified.
17 #pragma omp target map(from: err) map(to: sep)
19 err = t[0] != 1 || t[1] != 2 || t[2] != 3;
23 // But explicit zero length array section mapping does.
24 #pragma omp target map(from: err) map(tofrom: s.r[:0], t[:0])
27 /* Since OpenMP 5.2, if no matching mapped list it has been found,
28 pointers retain their original value. */
29 err = s.r == (int *) 0 || t == (int *) 0;
31 err = t[0] != 1 || t[1] != 2 || t[2] != 3 || s.r[0] != 6 || s.r[1] != 7;
34 // Similarly zero length array section, but unknown at compile time.
35 #pragma omp target map(from: err) map(tofrom: s.r[:z], t[:z])
38 /* Since OpenMP 5.2, if no matching mapped list it has been found,
39 pointers retain their original value. */
40 err = s.r == (int *) 0 || t == (int *) 0;
42 err = t[0] != 1 || t[1] != 2 || t[2] != 3 || s.r[0] != 6 || s.r[1] != 7;
45 #pragma omp target enter data map (to: s.r, t)
46 // But when already mapped, it binds to existing mappings.
47 #pragma omp target map(from: err) map(tofrom: s.r[:0], t[:0])
49 err = t[0] != 1 || t[1] != 2 || t[2] != 3 || s.r[0] != 6 || s.r[1] != 7;
53 #pragma omp target map(from: err) map(tofrom: s.r[:z], t[:z])
55 err = t[0] != 1 || t[1] != 2 || t[2] != 3 || s.r[0] != 6 || s.r[1] != 7;
64 int t[3] = { 1, 2, 3 };