Bug Summary

File:/tmp/pyrefcon/scipy/scipy/sparse/sparsetools/sparsetools.cxx
Warning:line 569, column 9
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sparsetools.cxx -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 -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/scipy/csa-scan,ctu-index-name=/tmp/pyrefcon/scipy/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/scipy/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/scipy -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -D __STDC_FORMAT_MACROS=1 -D NPY_NO_DEPRECATED_API=NPY_1_9_API_VERSION -D NO_ATLAS_INFO=1 -D HAVE_CBLAS -I scipy/sparse/sparsetools -I /usr/lib/python3/dist-packages/numpy/core/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wsign-compare -Wall -Wformat -Werror=format-security -Wformat -Werror=format-security -Wdate-time -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/tmp/pyrefcon/scipy -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/scipy/csa-scan/reports -x c++ scipy/sparse/sparsetools/sparsetools.cxx

scipy/sparse/sparsetools/sparsetools.cxx

1/*
2 * sparsetools.cxx
3 *
4 * Python module wrapping the sparsetools C++ routines.
5 *
6 * Each C++ routine is templated vs. an integer (I) and a data (T) parameter.
7 * The `generate_sparsetools.py` script generates `*_impl.h` headers
8 * that contain thunk functions with a datatype-based switch statement calling
9 * each templated instantiation.
10 *
11 * `generate_sparsetools.py` also generates a PyMethodDef list of Python
12 * routines and the corresponding functions call the thunk functions via
13 * `call_thunk`.
14 *
15 * The `call_thunk` function below determines the templated I and T data types
16 * based on the Python arguments. It then allocates arrays with pointers to
17 * the raw data, with appropriate types, and calls the thunk function after
18 * that.
19 *
20 * The types of arguments are specified by a "spec". This is given in a format
21 * where one character represents one argument. The one-character values are
22 * listed below in the call_spec function.
23 */
24
25#define PY_ARRAY_UNIQUE_SYMBOL_scipy_sparse_sparsetools_ARRAY_API _scipy_sparse_sparsetools_ARRAY_API
26
27#include <Python.h>
28
29#include <string>
30#include <stdexcept>
31#include <vector>
32#include <cstdlib>
33
34#include "numpy/ndarrayobject.h"
35
36#include "sparsetools.h"
37#include "util.h"
38
39#define MAX_ARGS16 16
40
41#if NPY_API_VERSION0x0000000D >= 0x0000000c
42 #define HAVE_WRITEBACKIFCOPY
43#endif
44
45static const int supported_I_typenums[] = {NPY_INT32NPY_INT, NPY_INT64NPY_LONG};
46static const int n_supported_I_typenums = sizeof(supported_I_typenums) / sizeof(int);
47
48static const int supported_T_typenums[] = {NPY_BOOL,
49 NPY_BYTE, NPY_UBYTE,
50 NPY_SHORT, NPY_USHORT,
51 NPY_INT, NPY_UINT,
52 NPY_LONG, NPY_ULONG,
53 NPY_LONGLONG, NPY_ULONGLONG,
54 NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
55 NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE};
56static const int n_supported_T_typenums = sizeof(supported_T_typenums) / sizeof(int);
57
58static PyObject *array_from_std_vector_and_free(int typenum, void *p);
59static void *allocate_std_vector_typenum(int typenum);
60static void free_std_vector_typenum(int typenum, void *p);
61static PyObject *c_array_from_object(PyObject *obj, int typenum, int is_output);
62
63
64/*
65 * Call a thunk function, dealing with input and output arrays.
66 *
67 * Resolves the templated <integer> and <data> dtypes from the `args` argument
68 * list.
69 *
70 * Parameters
71 * ----------
72 * ret_spec : {'i', 'v'}
73 * Return value spec. 'i' for integer, 'v' for void.
74 * spec
75 * String whose each character specifies a types of an
76 * argument:
77 *
78 * 'i': <integer> scalar
79 * 'I': <integer> array
80 * 'T': <data> array
81 * 'V': std::vector<integer>
82 * 'W': std::vector<data>
83 * 'B': npy_bool array
84 * '*': indicates that the next argument is an output argument
85 * thunk : PY_LONG_LONG thunk(int I_typenum, int T_typenum, void **)
86 * Thunk function to call. It is passed a void** array of pointers to
87 * arguments, constructed according to `spec`. The types of data pointed
88 * to by each element agree with I_typenum and T_typenum, or are bools.
89 * args
90 * Python tuple containing unprocessed arguments.
91 *
92 * Returns
93 * -------
94 * return_value
95 * The Python return value
96 *
97 */
98NPY_VISIBILITY_HIDDEN__attribute__((visibility("hidden"))) PyObject *
99call_thunk(char ret_spec, const char *spec, thunk_t *thunk, PyObject *args)
100{
101 void *arg_list[MAX_ARGS16];
102 PyObject *arg_arrays[MAX_ARGS16];
103 int is_output[MAX_ARGS16];
104 PyObject *return_value = NULL__null;
105 int I_typenum = NPY_INT32NPY_INT;
106 int T_typenum = -1;
107 int VW_count = 0;
108 int I_in_arglist = 0;
109 int T_in_arglist = 0;
110 int next_is_output = 0;
111 int j, k, arg_j;
112 const char *p;
113 PY_LONG_LONGlong long ret;
114 Py_ssize_t max_array_size = 0;
115 NPY_BEGIN_THREADS_DEFPyThreadState *_save=__null;;
116
117 if (!PyTuple_Check(args)((((((PyObject*)(args))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
118 PyErr_SetString(PyExc_ValueError, "args is not a tuple");
119 return NULL__null;
120 }
121
122 for (j = 0; j < MAX_ARGS16; ++j) {
123 arg_list[j] = NULL__null;
124 arg_arrays[j] = NULL__null;
125 is_output[j] = 0;
126 }
127
128
129 /*
130 * Detect data types in the signature
131 */
132 arg_j = 0;
133 j = 0;
134 for (p = spec; *p != '\0'; ++p, ++j, ++arg_j) {
135 const int *supported_typenums;
136 int n_supported_typenums;
137 int cur_typenum;
138 PyObject *arg;
139
140 if (j >= MAX_ARGS16) {
141 PyErr_SetString(PyExc_ValueError,
142 "internal error: too many arguments in spec");
143 goto fail;
144 }
145
146 is_output[j] = next_is_output;
147 next_is_output = 0;
148
149 switch (*p) {
150 case '*':
151 next_is_output = 1;
152 --j;
153 --arg_j;
154 continue;
155 case 'i':
156 case 'l':
157 /* Integer scalars */
158 arg = PyTuple_GetItem(args, arg_j);
159 if (arg == NULL__null) {
160 goto fail;
161 }
162 Py_INCREF(arg)_Py_INCREF(((PyObject*)(arg)));
163 arg_arrays[j] = arg;
164 continue;
165 case 'I':
166 /* Integer arrays */
167 supported_typenums = supported_I_typenums;
168 n_supported_typenums = n_supported_I_typenums;
169 cur_typenum = I_typenum;
170 I_in_arglist = 1;
171 break;
172 case 'T':
173 /* Data arrays */
174 supported_typenums = supported_T_typenums;
175 n_supported_typenums = n_supported_T_typenums;
176 cur_typenum = T_typenum;
177 T_in_arglist = 1;
178 break;
179 case 'B':
180 /* Boolean arrays */
181 arg = PyTuple_GetItem(args, arg_j);
182 if (arg == NULL__null) {
183 goto fail;
184 }
185 arg_arrays[j] = c_array_from_object(arg, NPY_BOOL, is_output[j]);
186 if (arg_arrays[j] == NULL__null) {
187 goto fail;
188 }
189 continue;
190 case 'V':
191 /* std::vector integer output array */
192 I_in_arglist = 1;
193 --arg_j;
194 VW_count += 1;
195 continue;
196 case 'W':
197 /* std::vector data output array */
198 T_in_arglist = 1;
199 --arg_j;
200 VW_count += 1;
201 continue;
202 default:
203 PyErr_SetString(PyExc_ValueError, "unknown character in spec");
204 goto fail;
205 }
206
207 arg = PyTuple_GetItem(args, arg_j);
208 if (arg == NULL__null) {
209 goto fail;
210 }
211 arg_arrays[j] = c_array_from_object(arg, -1, is_output[j]);
212 if (arg_arrays[j] == NULL__null) {
213 goto fail;
214 }
215
216 /* Find a compatible supported data type */
217
218 for (k = 0; k < n_supported_typenums; ++k) {
219 if (PyArray_CanCastSafely(*(int (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API[52]
)
(PyArray_TYPE((PyArrayObject *)arg_arrays[j]), supported_typenums[k]) &&
220 (cur_typenum == -1 || PyArray_CanCastSafely(*(int (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API[52]
)
(cur_typenum, supported_typenums[k])))
221 {
222 cur_typenum = supported_typenums[k];
223 break;
224 }
225 }
226 if (k == n_supported_typenums) {
227 PyErr_SetString(PyExc_ValueError,
228 "unsupported data types in input");
229 goto fail;
230 }
231
232 if (*p == 'I') {
233 I_typenum = cur_typenum;
234 }
235 else {
236 T_typenum = cur_typenum;
237 }
238 }
239
240 if (arg_j != PyTuple_Size(args)) {
241 PyErr_SetString(PyExc_ValueError, "too many arguments");
242 goto fail;
243 }
244
245 if ((I_in_arglist && I_typenum == -1) ||
246 (T_in_arglist && T_typenum == -1)) {
247 PyErr_SetString(PyExc_ValueError,
248 "unsupported data types in input");
249 goto fail;
250 }
251
252
253 /*
254 * Cast and extract argument arrays
255 */
256 j = 0;
257 for (p = spec; *p != '\0'; ++p, ++j) {
258 PyObject *arg;
259 int cur_typenum;
260
261 if (*p == '*') {
262 --j;
263 continue;
264 }
265 else if (*p == 'i' || *p == 'l') {
266 /* Integer scalars */
267 PY_LONG_LONGlong long value;
268
269 value = PyLong_AsLongLong(arg_arrays[j]);
270 if (PyErr_Occurred()) {
271 goto fail;
272 }
273
274 if ((*p == 'l' || PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(I_typenum, NPY_INT64NPY_LONG))
275 && value == (npy_int64)value) {
276 arg_list[j] = std::malloc(sizeof(npy_int64));
277 *(npy_int64*)arg_list[j] = (npy_int64)value;
278 }
279 else if (*p == 'i' && PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(I_typenum, NPY_INT32NPY_INT)
280 && value == (npy_int32)value) {
281 arg_list[j] = std::malloc(sizeof(npy_int32));
282 *(npy_int32*)arg_list[j] = (npy_int32)value;
283 }
284 else {
285 PyErr_SetString(PyExc_ValueError,
286 "could not convert integer scalar");
287 goto fail;
288 }
289 continue;
290 }
291 else if (*p == 'B') {
292 /* Boolean arrays already cast */
293 }
294 else if (*p == 'V') {
295 arg_list[j] = allocate_std_vector_typenum(I_typenum);
296 if (arg_list[j] == NULL__null) {
297 goto fail;
298 }
299 continue;
300 }
301 else if (*p == 'W') {
302 arg_list[j] = allocate_std_vector_typenum(T_typenum);
303 if (arg_list[j] == NULL__null) {
304 goto fail;
305 }
306 continue;
307 }
308 else {
309 cur_typenum = (*p == 'I' || *p == 'i') ? I_typenum : T_typenum;
310
311 /* Cast if necessary */
312 arg = arg_arrays[j];
313 if (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(PyArray_TYPE((PyArrayObject *)arg), cur_typenum)) {
314 /* No cast needed. */
315 }
316 else if (!is_output[j] || PyArray_CanCastSafely(*(int (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API[52]
)
(cur_typenum, PyArray_TYPE((PyArrayObject *)arg))) {
317 /* Cast needed. Output arrays require safe cast back. */
318 arg_arrays[j] = c_array_from_object(arg, cur_typenum, is_output[j]);
319 Py_DECREF(arg)_Py_DECREF(((PyObject*)(arg)));
320 if (arg_arrays[j] == NULL__null) {
321 goto fail;
322 }
323 }
324 else {
325 /* Cast back into output array was not safe. */
326 PyErr_SetString(PyExc_ValueError,
327 "Output dtype not compatible with inputs.");
328 goto fail;
329 }
330 }
331
332 /* Grab value */
333 arg_list[j] = PyArray_DATA((PyArrayObject *)arg_arrays[j]);
334
335 /* Find maximum array size */
336 if (PyArray_SIZE((PyArrayObject *)arg_arrays[j])(*(npy_intp (*)(npy_intp const *, int)) _scipy_sparse_sparsetools_ARRAY_API
[158])(PyArray_DIMS((PyArrayObject *)arg_arrays[j]), PyArray_NDIM
((PyArrayObject *)arg_arrays[j]))
> max_array_size) {
337 max_array_size = PyArray_SIZE((PyArrayObject *)arg_arrays[j])(*(npy_intp (*)(npy_intp const *, int)) _scipy_sparse_sparsetools_ARRAY_API
[158])(PyArray_DIMS((PyArrayObject *)arg_arrays[j]), PyArray_NDIM
((PyArrayObject *)arg_arrays[j]))
;
338 }
339 }
340
341
342 /*
343 * Call thunk
344 */
345 if (max_array_size > 100) {
346 /* Threshold GIL release: it's not a free operation */
347 NPY_BEGIN_THREADSdo {_save = PyEval_SaveThread();} while (0);;
348 }
349 try {
350 ret = thunk(I_typenum, T_typenum, arg_list);
351 NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = __null
;} } while (0);
;
352 } catch (const std::bad_alloc &e) {
353 NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = __null
;} } while (0);
;
354 PyErr_SetString(PyExc_MemoryError, e.what());
355 goto fail;
356 } catch (const std::exception &e) {
357 NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = __null
;} } while (0);
;
358 PyErr_SetString(PyExc_RuntimeError, e.what());
359 goto fail;
360 }
361
362 /*
363 * Generate return value;
364 */
365
366 switch (ret_spec) {
367 case 'i':
368 case 'l':
369 return_value = PyLong_FromLongLong(ret);
370 break;
371 case 'v':
372 Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct))));
373 return_value = Py_None(&_Py_NoneStruct);
374 break;
375 default:
376 PyErr_SetString(PyExc_ValueError,
377 "internal error: invalid return value spec");
378 }
379
380 /*
381 * Convert any std::vector output arrays to arrays
382 */
383 if (VW_count > 0) {
384 PyObject *new_ret;
385 PyObject *old_ret = return_value;
386 int pos;
387
388 return_value = NULL__null;
389
390 new_ret = PyTuple_New(VW_count + (old_ret == Py_None(&_Py_NoneStruct) ? 0 : 1));
391 if (new_ret == NULL__null) {
392 goto fail;
393 }
394 if (old_ret != Py_None(&_Py_NoneStruct)) {
395 PyTuple_SET_ITEM(new_ret, 0, old_ret)PyTuple_SetItem(new_ret, 0, old_ret);
396 pos = 1;
397 }
398 else {
399 Py_DECREF(old_ret)_Py_DECREF(((PyObject*)(old_ret)));
400 pos = 0;
401 }
402
403 j = 0;
404 for (p = spec; *p != '\0'; ++p, ++j) {
405 if (*p == '*') {
406 --j;
407 continue;
408 }
409 else if (*p == 'V' || *p == 'W') {
410 PyObject *arg;
411 if (*p == 'V') {
412 arg = array_from_std_vector_and_free(I_typenum, arg_list[j]);
413 } else {
414 arg = array_from_std_vector_and_free(T_typenum, arg_list[j]);
415 }
416 arg_list[j] = NULL__null;
417 if (arg == NULL__null) {
418 Py_XDECREF(new_ret)_Py_XDECREF(((PyObject*)(new_ret)));
419 goto fail;
420 }
421 PyTuple_SET_ITEM(new_ret, pos, arg)PyTuple_SetItem(new_ret, pos, arg);
422 ++pos;
423 }
424 }
425
426 return_value = new_ret;
427 }
428
429
430fail:
431 /*
432 * Cleanup
433 */
434 for (j = 0, p = spec; *p != '\0'; ++p, ++j) {
435 if (*p == '*') {
436 --j;
437 continue;
438 }
439 #ifdef HAVE_WRITEBACKIFCOPY
440 if (is_output[j] && arg_arrays[j] != NULL__null && PyArray_Check(arg_arrays[j])((((PyObject*)(arg_arrays[j]))->ob_type) == (&(*(PyTypeObject
*)_scipy_sparse_sparsetools_ARRAY_API[2])) || PyType_IsSubtype
((((PyObject*)(arg_arrays[j]))->ob_type), (&(*(PyTypeObject
*)_scipy_sparse_sparsetools_ARRAY_API[2]))))
) {
441 PyArray_ResolveWritebackIfCopy(*(int (*)(PyArrayObject *)) _scipy_sparse_sparsetools_ARRAY_API
[302])
((PyArrayObject *)arg_arrays[j]);
442 }
443 #endif
444 Py_XDECREF(arg_arrays[j])_Py_XDECREF(((PyObject*)(arg_arrays[j])));
445 if ((*p == 'i' || *p == 'l') && arg_list[j] != NULL__null) {
446 std::free(arg_list[j]);
447 }
448 else if (*p == 'V' && arg_list[j] != NULL__null) {
449 free_std_vector_typenum(I_typenum, arg_list[j]);
450 }
451 else if (*p == 'W' && arg_list[j] != NULL__null) {
452 free_std_vector_typenum(T_typenum, arg_list[j]);
453 }
454 }
455 return return_value;
456}
457
458
459/*
460 * Helper functions for dealing with std::vector templated instantiation.
461 */
462
463static void *allocate_std_vector_typenum(int typenum)
464{
465#define PROCESS(ntype, ctype) \
466 if (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(typenum, ntype)) { \
467 return (void*)(new std::vector<ctype>()); \
468 }
469
470 try {
471 SPTOOLS_FOR_EACH_DATA_TYPE_CODE(PROCESS)PROCESS(NPY_BOOL, npy_bool_wrapper) PROCESS(NPY_BYTE, npy_byte
) PROCESS(NPY_UBYTE, npy_ubyte) PROCESS(NPY_SHORT, npy_short)
PROCESS(NPY_USHORT, npy_ushort) PROCESS(NPY_INT, npy_int) PROCESS
(NPY_UINT, npy_uint) PROCESS(NPY_LONG, npy_long) PROCESS(NPY_ULONG
, npy_ulong) PROCESS(NPY_LONGLONG, npy_longlong) PROCESS(NPY_ULONGLONG
, npy_ulonglong) PROCESS(NPY_FLOAT, npy_float) PROCESS(NPY_DOUBLE
, npy_double) PROCESS(NPY_LONGDOUBLE, npy_longdouble) PROCESS
(NPY_CFLOAT, npy_cfloat_wrapper) PROCESS(NPY_CDOUBLE, npy_cdouble_wrapper
) PROCESS(NPY_CLONGDOUBLE, npy_clongdouble_wrapper)
472 } catch (std::exception &e) {
473 /* failed */
474 }
475
476#undef PROCESS
477
478 PyErr_SetString(PyExc_RuntimeError,
479 "failed to allocate std::vector");
480 return NULL__null;
481}
482
483static void free_std_vector_typenum(int typenum, void *p)
484{
485#define PROCESS(ntype, ctype) \
486 if (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(typenum, ntype)) { \
487 delete ((std::vector<ctype>*)p); \
488 return; \
489 }
490
491 SPTOOLS_FOR_EACH_DATA_TYPE_CODE(PROCESS)PROCESS(NPY_BOOL, npy_bool_wrapper) PROCESS(NPY_BYTE, npy_byte
) PROCESS(NPY_UBYTE, npy_ubyte) PROCESS(NPY_SHORT, npy_short)
PROCESS(NPY_USHORT, npy_ushort) PROCESS(NPY_INT, npy_int) PROCESS
(NPY_UINT, npy_uint) PROCESS(NPY_LONG, npy_long) PROCESS(NPY_ULONG
, npy_ulong) PROCESS(NPY_LONGLONG, npy_longlong) PROCESS(NPY_ULONGLONG
, npy_ulonglong) PROCESS(NPY_FLOAT, npy_float) PROCESS(NPY_DOUBLE
, npy_double) PROCESS(NPY_LONGDOUBLE, npy_longdouble) PROCESS
(NPY_CFLOAT, npy_cfloat_wrapper) PROCESS(NPY_CDOUBLE, npy_cdouble_wrapper
) PROCESS(NPY_CLONGDOUBLE, npy_clongdouble_wrapper)
492
493#undef PROCESS
494}
495
496static PyObject *array_from_std_vector_and_free(int typenum, void *p)
497{
498#define PROCESS(ntype, ctype) \
499 if (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_sparsetools_ARRAY_API
[191])
(typenum, ntype)) { \
500 std::vector<ctype> *v = (std::vector<ctype>*)p; \
501 npy_intp length = v->size(); \
502 PyObject *obj = PyArray_SimpleNew(1, &length, typenum)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_sparsetools_ARRAY_API
[93])(&(*(PyTypeObject *)_scipy_sparse_sparsetools_ARRAY_API
[2]), 1, &length, typenum, __null, __null, 0, 0, __null)
; \
503 if (length > 0) { \
504 memcpy(PyArray_DATA((PyArrayObject *)obj), &((*v)[0]), \
505 sizeof(ctype)*length); \
506 } \
507 delete v; \
508 return obj; \
509 }
510
511 SPTOOLS_FOR_EACH_DATA_TYPE_CODE(PROCESS)PROCESS(NPY_BOOL, npy_bool_wrapper) PROCESS(NPY_BYTE, npy_byte
) PROCESS(NPY_UBYTE, npy_ubyte) PROCESS(NPY_SHORT, npy_short)
PROCESS(NPY_USHORT, npy_ushort) PROCESS(NPY_INT, npy_int) PROCESS
(NPY_UINT, npy_uint) PROCESS(NPY_LONG, npy_long) PROCESS(NPY_ULONG
, npy_ulong) PROCESS(NPY_LONGLONG, npy_longlong) PROCESS(NPY_ULONGLONG
, npy_ulonglong) PROCESS(NPY_FLOAT, npy_float) PROCESS(NPY_DOUBLE
, npy_double) PROCESS(NPY_LONGDOUBLE, npy_longdouble) PROCESS
(NPY_CFLOAT, npy_cfloat_wrapper) PROCESS(NPY_CDOUBLE, npy_cdouble_wrapper
) PROCESS(NPY_CLONGDOUBLE, npy_clongdouble_wrapper)
512
513#undef PROCESS
514
515 PyErr_SetString(PyExc_RuntimeError,
516 "failed to convert std::vector output array");
517 return NULL__null;
518}
519
520static PyObject *c_array_from_object(PyObject *obj, int typenum, int is_output)
521{
522 if (!is_output) {
523 if (typenum == -1) {
524 return PyArray_FROM_OF(obj, NPY_ARRAY_C_CONTIGUOUS|NPY_ARRAY_NOTSWAPPED)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _scipy_sparse_sparsetools_ARRAY_API[108])(obj, __null
, 0, 0, 0x0001|0x0200, __null)
;
525 }
526 else {
527 return PyArray_FROM_OTF(obj, typenum, NPY_ARRAY_C_CONTIGUOUS|NPY_ARRAY_NOTSWAPPED)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _scipy_sparse_sparsetools_ARRAY_API[69])(obj, (
*(PyArray_Descr * (*)(int)) _scipy_sparse_sparsetools_ARRAY_API
[45])(typenum), 0, 0, (((0x0001|0x0200) & 0x0020) ? ((0x0001
|0x0200) | ((0x0001 | (0x0100 | 0x0400)))) : (0x0001|0x0200))
, __null)
;
528 }
529 }
530 else {
531 #ifdef HAVE_WRITEBACKIFCOPY
532 int flags = NPY_ARRAY_C_CONTIGUOUS0x0001|NPY_ARRAY_WRITEABLE0x0400|NPY_ARRAY_WRITEBACKIFCOPY0x2000|NPY_ARRAY_NOTSWAPPED0x0200;
533 #else
534 int flags = NPY_ARRAY_C_CONTIGUOUS0x0001|NPY_ARRAY_WRITEABLE0x0400|NPY_UPDATEIFCOPY|NPY_ARRAY_NOTSWAPPED0x0200;
535 #endif
536 if (typenum == -1) {
537 return PyArray_FROM_OF(obj, flags)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _scipy_sparse_sparsetools_ARRAY_API[108])(obj, __null
, 0, 0, flags, __null)
;
538 }
539 else {
540 return PyArray_FROM_OTF(obj, typenum, flags)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _scipy_sparse_sparsetools_ARRAY_API[69])(obj, (
*(PyArray_Descr * (*)(int)) _scipy_sparse_sparsetools_ARRAY_API
[45])(typenum), 0, 0, (((flags) & 0x0020) ? ((flags) | ((
0x0001 | (0x0100 | 0x0400)))) : (flags)), __null)
;
541 }
542 }
543}
544
545
546/*
547 * Python module initialization
548 */
549
550extern "C" {
551
552#include "sparsetools_impl.h"
553
554static struct PyModuleDef moduledef = {
555 PyModuleDef_HEAD_INIT{ { 1, __null }, __null, 0, __null, },
556 "_sparsetools",
557 NULL__null,
558 -1,
559 sparsetools_methods,
560 NULL__null,
561 NULL__null,
562 NULL__null,
563 NULL__null
564};
565
566PyObject *PyInit__sparsetools(void)
567{
568 PyObject *m;
569 m = PyModule_Create(&moduledef)PyModule_Create2(&moduledef, 1013);
1
Calling 'PyModule_Create2'
3
Returning from 'PyModule_Create2'
5
PyObject ownership leak with reference count of 1
570 import_array(){if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(
PyExc_ImportError, "numpy.core.multiarray failed to import");
return __null; } }
;
4
Taking true branch
571 return m;
572}
573
574} /* extern "C" */

/opt/pyrefcon/lib/pyrefcon/models/models/PyModule_Create2.model

1#ifndef PyModule_Create2
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version) {
6 return clang_analyzer_PyObject_New_Reference();
2
Setting reference count to 1
7}
8#else
9#warning "API PyModule_Create2 is defined as a macro."
10#endif