clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name api.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D omptarget_EXPORTS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/projects/openmp/libomptarget/src -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/libomptarget/src -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/libomptarget/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/projects/openmp/libomptarget/src -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/libomptarget/src/api.cpp -faddrsig
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include <omptarget.h> |
15 | |
16 | #include "device.h" |
17 | #include "private.h" |
18 | #include "rtl.h" |
19 | |
20 | #include <climits> |
21 | #include <cstring> |
22 | #include <cstdlib> |
23 | |
24 | EXTERNextern "C" int omp_get_num_devices(void) { |
25 | RTLsMtx.lock(); |
26 | size_t Devices_size = Devices.size(); |
27 | RTLsMtx.unlock(); |
28 | |
29 | DP("Call to omp_get_num_devices returning %zd\n", Devices_size){}; |
30 | |
31 | return Devices_size; |
32 | } |
33 | |
34 | EXTERNextern "C" int omp_get_initial_device(void) { |
35 | DP("Call to omp_get_initial_device returning %d\n", HOST_DEVICE){}; |
36 | return HOST_DEVICE-10; |
37 | } |
38 | |
39 | EXTERNextern "C" void *omp_target_alloc(size_t size, int device_num) { |
40 | DP("Call to omp_target_alloc for device %d requesting %zu bytes\n",{} |
41 | device_num, size){}; |
42 | |
43 | if (size <= 0) { |
44 | DP("Call to omp_target_alloc with non-positive length\n"){}; |
45 | return NULL__null; |
46 | } |
47 | |
48 | void *rc = NULL__null; |
49 | |
50 | if (device_num == omp_get_initial_device()) { |
51 | rc = malloc(size); |
52 | DP("omp_target_alloc returns host ptr " DPxMOD "\n", DPxPTR(rc)){}; |
53 | return rc; |
54 | } |
55 | |
56 | if (!device_is_ready(device_num)) { |
57 | DP("omp_target_alloc returns NULL ptr\n"){}; |
58 | return NULL__null; |
59 | } |
60 | |
61 | DeviceTy &Device = Devices[device_num]; |
62 | rc = Device.RTL->data_alloc(Device.RTLDeviceID, size, NULL__null); |
63 | DP("omp_target_alloc returns device ptr " DPxMOD "\n", DPxPTR(rc)){}; |
64 | return rc; |
65 | } |
66 | |
67 | EXTERNextern "C" void omp_target_free(void *device_ptr, int device_num) { |
68 | DP("Call to omp_target_free for device %d and address " DPxMOD "\n",{} |
69 | device_num, DPxPTR(device_ptr)){}; |
70 | |
71 | if (!device_ptr) { |
72 | DP("Call to omp_target_free with NULL ptr\n"){}; |
73 | return; |
74 | } |
75 | |
76 | if (device_num == omp_get_initial_device()) { |
77 | free(device_ptr); |
78 | DP("omp_target_free deallocated host ptr\n"){}; |
79 | return; |
80 | } |
81 | |
82 | if (!device_is_ready(device_num)) { |
83 | DP("omp_target_free returns, nothing to do\n"){}; |
84 | return; |
85 | } |
86 | |
87 | DeviceTy &Device = Devices[device_num]; |
88 | Device.RTL->data_delete(Device.RTLDeviceID, (void *)device_ptr); |
89 | DP("omp_target_free deallocated device ptr\n"){}; |
90 | } |
91 | |
92 | EXTERNextern "C" int omp_target_is_present(void *ptr, int device_num) { |
93 | DP("Call to omp_target_is_present for device %d and address " DPxMOD "\n",{} |
94 | device_num, DPxPTR(ptr)){}; |
95 | |
96 | if (!ptr) { |
97 | DP("Call to omp_target_is_present with NULL ptr, returning false\n"){}; |
98 | return false; |
99 | } |
100 | |
101 | if (device_num == omp_get_initial_device()) { |
102 | DP("Call to omp_target_is_present on host, returning true\n"){}; |
103 | return true; |
104 | } |
105 | |
106 | RTLsMtx.lock(); |
107 | size_t Devices_size = Devices.size(); |
108 | RTLsMtx.unlock(); |
109 | if (Devices_size <= (size_t)device_num) { |
110 | DP("Call to omp_target_is_present with invalid device ID, returning "{} |
111 | "false\n"){}; |
112 | return false; |
113 | } |
114 | |
115 | DeviceTy& Device = Devices[device_num]; |
116 | bool IsLast; |
117 | int rc = (Device.getTgtPtrBegin(ptr, 0, IsLast, false) != NULL__null); |
118 | DP("Call to omp_target_is_present returns %d\n", rc){}; |
119 | return rc; |
120 | } |
121 | |
122 | EXTERNextern "C" int omp_target_memcpy(void *dst, void *src, size_t length, |
123 | size_t dst_offset, size_t src_offset, int dst_device, int src_device) { |
124 | DP("Call to omp_target_memcpy, dst device %d, src device %d, "{} |
125 | "dst addr " DPxMOD ", src addr " DPxMOD ", dst offset %zu, "{} |
126 | "src offset %zu, length %zu\n", dst_device, src_device, DPxPTR(dst),{} |
127 | DPxPTR(src), dst_offset, src_offset, length){}; |
128 | |
129 | if (!dst || !src || length <= 0) { |
130 | DP("Call to omp_target_memcpy with invalid arguments\n"){}; |
131 | return OFFLOAD_FAIL(~0); |
132 | } |
133 | |
134 | if (src_device != omp_get_initial_device() && !device_is_ready(src_device)) { |
135 | DP("omp_target_memcpy returns OFFLOAD_FAIL\n"){}; |
136 | return OFFLOAD_FAIL(~0); |
137 | } |
138 | |
139 | if (dst_device != omp_get_initial_device() && !device_is_ready(dst_device)) { |
140 | DP("omp_target_memcpy returns OFFLOAD_FAIL\n"){}; |
141 | return OFFLOAD_FAIL(~0); |
142 | } |
143 | |
144 | int rc = OFFLOAD_SUCCESS(0); |
145 | void *srcAddr = (char *)src + src_offset; |
146 | void *dstAddr = (char *)dst + dst_offset; |
147 | |
148 | if (src_device == omp_get_initial_device() && |
149 | dst_device == omp_get_initial_device()) { |
150 | DP("copy from host to host\n"){}; |
151 | const void *p = memcpy(dstAddr, srcAddr, length); |
152 | if (p == NULL__null) |
153 | rc = OFFLOAD_FAIL(~0); |
154 | } else if (src_device == omp_get_initial_device()) { |
155 | DP("copy from host to device\n"){}; |
156 | DeviceTy& DstDev = Devices[dst_device]; |
157 | rc = DstDev.data_submit(dstAddr, srcAddr, length); |
158 | } else if (dst_device == omp_get_initial_device()) { |
159 | DP("copy from device to host\n"){}; |
160 | DeviceTy& SrcDev = Devices[src_device]; |
161 | rc = SrcDev.data_retrieve(dstAddr, srcAddr, length); |
162 | } else { |
163 | DP("copy from device to device\n"){}; |
164 | void *buffer = malloc(length); |
165 | DeviceTy& SrcDev = Devices[src_device]; |
166 | DeviceTy& DstDev = Devices[dst_device]; |
167 | rc = SrcDev.data_retrieve(buffer, srcAddr, length); |
168 | if (rc == OFFLOAD_SUCCESS(0)) |
169 | rc = DstDev.data_submit(dstAddr, buffer, length); |
170 | } |
171 | |
172 | DP("omp_target_memcpy returns %d\n", rc){}; |
173 | return rc; |
174 | } |
175 | |
176 | EXTERNextern "C" int omp_target_memcpy_rect(void *dst, void *src, size_t element_size, |
177 | int num_dims, const size_t *volume, const size_t *dst_offsets, |
178 | const size_t *src_offsets, const size_t *dst_dimensions, |
179 | const size_t *src_dimensions, int dst_device, int src_device) { |
180 | DP("Call to omp_target_memcpy_rect, dst device %d, src device %d, "{} |
181 | "dst addr " DPxMOD ", src addr " DPxMOD ", dst offsets " DPxMOD ", "{} |
182 | "src offsets " DPxMOD ", dst dims " DPxMOD ", src dims " DPxMOD ", "{} |
183 | "volume " DPxMOD ", element size %zu, num_dims %d\n", dst_device,{} |
184 | src_device, DPxPTR(dst), DPxPTR(src), DPxPTR(dst_offsets),{} |
185 | DPxPTR(src_offsets), DPxPTR(dst_dimensions), DPxPTR(src_dimensions),{} |
186 | DPxPTR(volume), element_size, num_dims){}; |
187 | |
188 | if (!(dst || src)) { |
| 1 | Assuming 'dst' is non-null | |
|
| |
189 | DP("Call to omp_target_memcpy_rect returns max supported dimensions %d\n",{} |
190 | INT_MAX){}; |
191 | return INT_MAX2147483647; |
192 | } |
193 | |
194 | if (!dst || !src || element_size < 1 || num_dims < 1 || !volume || |
| 3 | | Assuming 'src' is non-null | |
|
| 4 | | Assuming 'element_size' is >= 1 | |
|
| 5 | | Assuming 'num_dims' is >= 1 | |
|
| 6 | | Assuming 'volume' is non-null | |
|
| |
195 | !dst_offsets || !src_offsets || !dst_dimensions || !src_dimensions) { |
| 7 | | Assuming 'dst_offsets' is non-null | |
|
| 8 | | Assuming 'src_offsets' is non-null | |
|
| 9 | | Assuming 'dst_dimensions' is non-null | |
|
| 10 | | Assuming 'src_dimensions' is non-null | |
|
196 | DP("Call to omp_target_memcpy_rect with invalid arguments\n"){}; |
197 | return OFFLOAD_FAIL(~0); |
198 | } |
199 | |
200 | int rc; |
| 12 | | 'rc' declared without an initial value | |
|
201 | if (num_dims == 1) { |
| 13 | | Assuming 'num_dims' is not equal to 1 | |
|
| |
202 | rc = omp_target_memcpy(dst, src, element_size * volume[0], |
203 | element_size * dst_offsets[0], element_size * src_offsets[0], |
204 | dst_device, src_device); |
205 | } else { |
206 | size_t dst_slice_size = element_size; |
207 | size_t src_slice_size = element_size; |
208 | for (int i=1; i<num_dims; ++i) { |
| 15 | | Loop condition is true. Entering loop body | |
|
| 16 | | Assuming 'i' is >= 'num_dims' | |
|
| 17 | | Loop condition is false. Execution continues on line 213 | |
|
209 | dst_slice_size *= dst_dimensions[i]; |
210 | src_slice_size *= src_dimensions[i]; |
211 | } |
212 | |
213 | size_t dst_off = dst_offsets[0] * dst_slice_size; |
214 | size_t src_off = src_offsets[0] * src_slice_size; |
215 | for (size_t i=0; i<volume[0]; ++i) { |
| 18 | | Assuming the condition is false | |
|
| 19 | | Loop condition is false. Execution continues on line 229 | |
|
216 | rc = omp_target_memcpy_rect((char *) dst + dst_off + dst_slice_size * i, |
217 | (char *) src + src_off + src_slice_size * i, element_size, |
218 | num_dims - 1, volume + 1, dst_offsets + 1, src_offsets + 1, |
219 | dst_dimensions + 1, src_dimensions + 1, dst_device, src_device); |
220 | |
221 | if (rc) { |
222 | DP("Recursive call to omp_target_memcpy_rect returns unsuccessfully\n"){}; |
223 | return rc; |
224 | } |
225 | } |
226 | } |
227 | |
228 | DP("omp_target_memcpy_rect returns %d\n", rc){}; |
229 | return rc; |
| 20 | | Undefined or garbage value returned to caller |
|
230 | } |
231 | |
232 | EXTERNextern "C" int omp_target_associate_ptr(void *host_ptr, void *device_ptr, |
233 | size_t size, size_t device_offset, int device_num) { |
234 | DP("Call to omp_target_associate_ptr with host_ptr " DPxMOD ", "{} |
235 | "device_ptr " DPxMOD ", size %zu, device_offset %zu, device_num %d\n",{} |
236 | DPxPTR(host_ptr), DPxPTR(device_ptr), size, device_offset, device_num){}; |
237 | |
238 | if (!host_ptr || !device_ptr || size <= 0) { |
239 | DP("Call to omp_target_associate_ptr with invalid arguments\n"){}; |
240 | return OFFLOAD_FAIL(~0); |
241 | } |
242 | |
243 | if (device_num == omp_get_initial_device()) { |
244 | DP("omp_target_associate_ptr: no association possible on the host\n"){}; |
245 | return OFFLOAD_FAIL(~0); |
246 | } |
247 | |
248 | if (!device_is_ready(device_num)) { |
249 | DP("omp_target_associate_ptr returns OFFLOAD_FAIL\n"){}; |
250 | return OFFLOAD_FAIL(~0); |
251 | } |
252 | |
253 | DeviceTy& Device = Devices[device_num]; |
254 | void *device_addr = (void *)((uint64_t)device_ptr + (uint64_t)device_offset); |
255 | int rc = Device.associatePtr(host_ptr, device_addr, size); |
256 | DP("omp_target_associate_ptr returns %d\n", rc){}; |
257 | return rc; |
258 | } |
259 | |
260 | EXTERNextern "C" int omp_target_disassociate_ptr(void *host_ptr, int device_num) { |
261 | DP("Call to omp_target_disassociate_ptr with host_ptr " DPxMOD ", "{} |
262 | "device_num %d\n", DPxPTR(host_ptr), device_num){}; |
263 | |
264 | if (!host_ptr) { |
265 | DP("Call to omp_target_associate_ptr with invalid host_ptr\n"){}; |
266 | return OFFLOAD_FAIL(~0); |
267 | } |
268 | |
269 | if (device_num == omp_get_initial_device()) { |
270 | DP("omp_target_disassociate_ptr: no association possible on the host\n"){}; |
271 | return OFFLOAD_FAIL(~0); |
272 | } |
273 | |
274 | if (!device_is_ready(device_num)) { |
275 | DP("omp_target_disassociate_ptr returns OFFLOAD_FAIL\n"){}; |
276 | return OFFLOAD_FAIL(~0); |
277 | } |
278 | |
279 | DeviceTy& Device = Devices[device_num]; |
280 | int rc = Device.disassociatePtr(host_ptr); |
281 | DP("omp_target_disassociate_ptr returns %d\n", rc){}; |
282 | return rc; |
283 | } |