Bug Summary

File:projects/openmp/libomptarget/src/api.cpp
Warning:line 229, column 3
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

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//===----------- api.cpp - Target independent OpenMP target RTL -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.txt for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Implementation of OpenMP API interface functions.
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
24EXTERNextern "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
34EXTERNextern "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
39EXTERNextern "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
67EXTERNextern "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
92EXTERNextern "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; // not used
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
122EXTERNextern "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
176EXTERNextern "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
2
Taking false branch
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
11
Taking false branch
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
14
Taking false branch
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
232EXTERNextern "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
260EXTERNextern "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}