1 extern "C" void abort ();
2 
3 __attribute__((noinline, noclone)) void
foo(int * & p,int * & q,int * & r,int n,int m)4 foo (int *&p, int *&q, int *&r, int n, int m)
5 {
6   int i, err, *s = r;
7   int sep = 1;
8   #pragma omp target map(to:sep)
9   sep = 0;
10   #pragma omp target data map(to:p[0:8])
11   {
12     /* For zero length array sections, p points to the start of
13        already mapped range, q to the end of it (with nothing mapped
14        after it), and r does not point to an mapped range.  */
15     #pragma omp target map(alloc:p[:0]) map(to:q[:0]) map(from:r[:0]) private(i) map(from:err) firstprivate (s)
16     {
17       err = 0;
18       for (i = 0; i < 8; i++)
19 	if (p[i] != i + 1)
20 	  err = 1;
21       if (sep)
22 	{
23 	  if (q != (int *) 0 || r != (int *) 0)
24 	    err = 1;
25 	}
26       else if (p + 8 != q || r != s)
27 	err = 1;
28     }
29     if (err)
30       abort ();
31     /* Implicit mapping of pointers behaves the same way.  */
32     #pragma omp target private(i) map(from:err) firstprivate (s)
33     {
34       err = 0;
35       for (i = 0; i < 8; i++)
36 	if (p[i] != i + 1)
37 	  err = 1;
38       if (sep)
39 	{
40 	  if (q != (int *) 0 || r != (int *) 0)
41 	    err = 1;
42 	}
43       else if (p + 8 != q || r != s)
44 	err = 1;
45     }
46     if (err)
47       abort ();
48     /* And zero-length array sections, though not known at compile
49        time, behave the same.  */
50     #pragma omp target map(p[:n]) map(tofrom:q[:n]) map(alloc:r[:n]) private(i) map(from:err) firstprivate (s)
51     {
52       err = 0;
53       for (i = 0; i < 8; i++)
54 	if (p[i] != i + 1)
55 	  err = 1;
56       if (sep)
57 	{
58 	  if (q != (int *) 0 || r != (int *) 0)
59 	    err = 1;
60 	}
61       else if (p + 8 != q || r != s)
62 	err = 1;
63     }
64     if (err)
65       abort ();
66     /* Non-zero length array sections, though not known at compile,
67        behave differently.  */
68     #pragma omp target map(p[:m]) map(tofrom:q[:m]) map(to:r[:m]) private(i) map(from:err)
69     {
70       err = 0;
71       for (i = 0; i < 8; i++)
72 	if (p[i] != i + 1)
73 	  err = 1;
74       if (q[0] != 9 || r[0] != 10)
75 	err = 1;
76     }
77     if (err)
78       abort ();
79     #pragma omp target data map(to:q[0:1])
80     {
81       /* For zero length array sections, p points to the start of
82 	 already mapped range, q points to the start of another one,
83 	 and r to the end of the second one.  */
84       #pragma omp target map(to:p[:0]) map(from:q[:0]) map(tofrom:r[:0]) private(i) map(from:err)
85       {
86 	err = 0;
87 	for (i = 0; i < 8; i++)
88 	  if (p[i] != i + 1)
89 	    err = 1;
90 	if (q[0] != 9)
91 	  err = 1;
92 	else if (sep)
93 	  {
94 	    if (r != (int *) 0)
95 	      err = 1;
96 	  }
97 	else if (r != q + 1)
98 	  err = 1;
99       }
100       if (err)
101 	abort ();
102       /* Implicit mapping of pointers behaves the same way.  */
103       #pragma omp target private(i) map(from:err)
104       {
105 	err = 0;
106 	for (i = 0; i < 8; i++)
107 	  if (p[i] != i + 1)
108 	    err = 1;
109 	if (q[0] != 9)
110 	  err = 1;
111 	else if (sep)
112 	  {
113 	    if (r != (int *) 0)
114 	      err = 1;
115 	  }
116 	else if (r != q + 1)
117 	  err = 1;
118       }
119       if (err)
120 	abort ();
121       /* And zero-length array sections, though not known at compile
122 	 time, behave the same.  */
123       #pragma omp target map(p[:n]) map(alloc:q[:n]) map(from:r[:n]) private(i) map(from:err)
124       {
125 	err = 0;
126 	for (i = 0; i < 8; i++)
127 	  if (p[i] != i + 1)
128 	    err = 1;
129 	if (q[0] != 9)
130 	  err = 1;
131 	else if (sep)
132 	  {
133 	    if (r != (int *) 0)
134 	      err = 1;
135 	  }
136 	else if (r != q + 1)
137 	  err = 1;
138       }
139       if (err)
140 	abort ();
141       /* Non-zero length array sections, though not known at compile,
142 	 behave differently.  */
143       #pragma omp target map(p[:m]) map(alloc:q[:m]) map(tofrom:r[:m]) private(i) map(from:err)
144       {
145 	err = 0;
146 	for (i = 0; i < 8; i++)
147 	  if (p[i] != i + 1)
148 	    err = 1;
149 	if (q[0] != 9 || r[0] != 10)
150 	  err = 1;
151       }
152       if (err)
153 	abort ();
154     }
155   }
156 }
157 
158 int
main()159 main ()
160 {
161   int a[32], i;
162   for (i = 0; i < 32; i++)
163     a[i] = i;
164   int *p = a + 1, *q = a + 9, *r = a + 10;
165   foo (p, q, r, 0, 1);
166   return 0;
167 }
168