| // A user-defined mapper maps s.y and, with present written directly in the |
| // mapper's own clause, the pointee s.p. present in the mapper clause applies at |
| // every OpenMP version -- this is not the outer-clause propagation that a |
| // follow-on gates on the version, so both 5.2 and 6.0 behave the same here. |
| // |
| // RUN: %libomptarget-compile-run-and-check-generic |
| // RUN: %libomptarget-compile-generic -DOUT_OF_BOUNDS |
| // RUN: %libomptarget-run-fail-generic 2>&1 \ |
| // RUN: | %fcheck-generic --check-prefix=CHECK-OOB |
| |
| #include <stdio.h> |
| |
| int x[10]; |
| typedef struct { |
| int y; |
| int *p; |
| } S; |
| |
| #ifdef OUT_OF_BOUNDS |
| // s.p[0:20] extends beyond the mapped region x[0:10]; the present check fails. |
| #pragma omp declare mapper(S s) map(s.y) map(present, tofrom : s.p[0 : 20]) |
| #else |
| #pragma omp declare mapper(S s) map(s.y) map(present, tofrom : s.p[0 : 2]) |
| #endif |
| S s; |
| |
| void f1() { |
| // The mapper runs here; for OUT_OF_BOUNDS the present check fails here. |
| #pragma omp target update to(s) |
| |
| #pragma omp target data use_device_addr(s, x) |
| #pragma omp target has_device_addr(s, x) |
| { |
| s.y = s.y + 222; |
| x[0] = x[0] + 222; |
| } |
| } |
| |
| int main() { |
| x[0] = 111; |
| s.y = 111; |
| s.p = &x[0]; |
| |
| // CHECK-OOB: addr=0x[[#%x,HOST_ADDR:]], size=[[#%u,SIZE:]] |
| fprintf(stderr, "addr=%p, size=%zu\n", &s.p[0], 20 * sizeof(s.p[0])); |
| |
| #pragma omp target data map(from : s.y, x) |
| { |
| f1(); |
| } |
| |
| printf("%d %d\n", x[0], s.y); // CHECK: 333 333 |
| // clang-format off |
| // CHECK-OOB: message: device mapping required by 'present' motion modifier does not exist for host address 0x{{0*}}[[#HOST_ADDR]] ([[#SIZE]] bytes) |
| // CHECK-OOB: fatal error 1: failure of target construct while offloading is mandatory |
| // clang-format on |
| } |