Bug Summary

File:numpy/core/src/umath/umathmodule.c
Warning:line 283, column 35
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 umathmodule.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -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/numpy/csa-scan,ctu-index-name=/tmp/pyrefcon/numpy/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/numpy/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 -target-feature +sse -target-feature +sse2 -target-feature +sse3 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/numpy -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -D NPY_INTERNAL_BUILD=1 -D HAVE_NPY_CONFIG_H=1 -D _FILE_OFFSET_BITS=64 -D _LARGEFILE_SOURCE=1 -D _LARGEFILE64_SOURCE=1 -I build/src.linux-x86_64-3.8/numpy/core/src/common -I build/src.linux-x86_64-3.8/numpy/core/src/umath -I numpy/core/include -I build/src.linux-x86_64-3.8/numpy/core/include/numpy -I build/src.linux-x86_64-3.8/numpy/distutils/include -I numpy/core/src/common -I numpy/core/src -I numpy/core -I numpy/core/src/npymath -I numpy/core/src/multiarray -I numpy/core/src/umath -I numpy/core/src/npysort -I numpy/core/src/_simd -I build/src.linux-x86_64-3.8/numpy/core/src/common -I build/src.linux-x86_64-3.8/numpy/core/src/npymath -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 -fdebug-compilation-dir=/tmp/pyrefcon/numpy -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/numpy/csa-scan/reports -x c numpy/core/src/umath/umathmodule.c

numpy/core/src/umath/umathmodule.c

1/* -*- c -*- */
2
3/*
4 * vim:syntax=c
5 */
6
7/*
8 *****************************************************************************
9 ** INCLUDES **
10 *****************************************************************************
11 */
12
13/*
14 * _UMATHMODULE IS needed in __ufunc_api.h, included from numpy/ufuncobject.h.
15 * This is a mess and it would be nice to fix it. It has nothing to do with
16 * __ufunc_api.c
17 */
18#define _UMATHMODULE
19#define _MULTIARRAYMODULE
20#define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E
21
22#include "Python.h"
23
24#include "npy_config.h"
25
26#include "numpy/arrayobject.h"
27#include "numpy/ufuncobject.h"
28#include "numpy/npy_3kcompat.h"
29#include "abstract.h"
30
31#include "numpy/npy_math.h"
32#include "number.h"
33
34static PyUFuncGenericFunction pyfunc_functions[] = {PyUFunc_On_Om};
35
36static int
37object_ufunc_type_resolver(PyUFuncObject *ufunc,
38 NPY_CASTING casting,
39 PyArrayObject **operands,
40 PyObject *type_tup,
41 PyArray_Descr **out_dtypes)
42{
43 int i, nop = ufunc->nin + ufunc->nout;
44
45 out_dtypes[0] = PyArray_DescrFromType(NPY_OBJECT);
46 if (out_dtypes[0] == NULL((void*)0)) {
47 return -1;
48 }
49
50 for (i = 1; i < nop; ++i) {
51 Py_INCREF(out_dtypes[0])_Py_INCREF(((PyObject*)(out_dtypes[0])));
52 out_dtypes[i] = out_dtypes[0];
53 }
54
55 return 0;
56}
57
58static int
59object_ufunc_loop_selector(PyUFuncObject *ufunc,
60 PyArray_Descr **NPY_UNUSED(dtypes)(__NPY_UNUSED_TAGGEDdtypes) __attribute__ ((__unused__)),
61 PyUFuncGenericFunction *out_innerloop,
62 void **out_innerloopdata,
63 int *out_needs_api)
64{
65 *out_innerloop = ufunc->functions[0];
66 *out_innerloopdata = ufunc->data[0];
67 *out_needs_api = 1;
68
69 return 0;
70}
71
72PyObject *
73ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy)(__NPY_UNUSED_TAGGEDdummy) __attribute__ ((__unused__)), PyObject *args, PyObject *kwds) {
74 PyObject *function, *pyname = NULL((void*)0);
75 int nin, nout, i, nargs;
76 PyUFunc_PyFuncData *fdata;
77 PyUFuncObject *self;
78 const char *fname = NULL((void*)0);
79 char *str, *types, *doc;
80 Py_ssize_t fname_len = -1;
81 void * ptr, **data;
82 int offset[2];
83 PyObject *identity = NULL((void*)0); /* note: not the same semantics as Py_None */
84 static char *kwlist[] = {"", "nin", "nout", "identity", NULL((void*)0)};
85
86 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii|$O:frompyfunc", kwlist,
87 &function, &nin, &nout, &identity)) {
88 return NULL((void*)0);
89 }
90 if (!PyCallable_Check(function)) {
91 PyErr_SetString(PyExc_TypeError, "function must be callable");
92 return NULL((void*)0);
93 }
94
95 nargs = nin + nout;
96
97 pyname = PyObject_GetAttrString(function, "__name__");
98 if (pyname) {
99 fname = PyUnicode_AsUTF8AndSize(pyname, &fname_len);
100 }
101 if (fname == NULL((void*)0)) {
102 PyErr_Clear();
103 fname = "?";
104 fname_len = 1;
105 }
106
107 /*
108 * ptr will be assigned to self->ptr, holds a pointer for enough memory for
109 * self->data[0] (fdata)
110 * self->data
111 * self->name
112 * self->types
113 *
114 * To be safest, all of these need their memory aligned on void * pointers
115 * Therefore, we may need to allocate extra space.
116 */
117 offset[0] = sizeof(PyUFunc_PyFuncData);
118 i = (sizeof(PyUFunc_PyFuncData) % sizeof(void *));
119 if (i) {
120 offset[0] += (sizeof(void *) - i);
121 }
122 offset[1] = nargs;
123 i = (nargs % sizeof(void *));
124 if (i) {
125 offset[1] += (sizeof(void *)-i);
126 }
127 ptr = PyArray_mallocPyMem_RawMalloc(offset[0] + offset[1] + sizeof(void *) +
128 (fname_len + 14));
129 if (ptr == NULL((void*)0)) {
130 Py_XDECREF(pyname)_Py_XDECREF(((PyObject*)(pyname)));
131 return PyErr_NoMemory();
132 }
133 fdata = (PyUFunc_PyFuncData *)(ptr);
134 fdata->callable = function;
135 fdata->nin = nin;
136 fdata->nout = nout;
137
138 data = (void **)(((char *)ptr) + offset[0]);
139 data[0] = (void *)fdata;
140 types = (char *)data + sizeof(void *);
141 for (i = 0; i < nargs; i++) {
142 types[i] = NPY_OBJECT;
143 }
144 str = types + offset[1];
145 memcpy(str, fname, fname_len);
146 memcpy(str+fname_len, " (vectorized)", 14);
147 Py_XDECREF(pyname)_Py_XDECREF(((PyObject*)(pyname)));
148
149 /* Do a better job someday */
150 doc = "dynamic ufunc based on a python function";
151
152 self = (PyUFuncObject *)PyUFunc_FromFuncAndDataAndSignatureAndIdentity(
153 (PyUFuncGenericFunction *)pyfunc_functions, data,
154 types, /* ntypes */ 1, nin, nout, identity ? PyUFunc_IdentityValue-3 : PyUFunc_None-1,
155 str, doc, /* unused */ 0, NULL((void*)0), identity);
156
157 if (self == NULL((void*)0)) {
158 PyArray_freePyMem_RawFree(ptr);
159 return NULL((void*)0);
160 }
161 Py_INCREF(function)_Py_INCREF(((PyObject*)(function)));
162 self->obj = function;
163 self->ptr = ptr;
164
165 self->type_resolver = &object_ufunc_type_resolver;
166 self->legacy_inner_loop_selector = &object_ufunc_loop_selector;
167 PyObject_GC_Track(self);
168
169 return (PyObject *)self;
170}
171
172/* docstring in numpy.add_newdocs.py */
173PyObject *
174add_newdoc_ufunc(PyObject *NPY_UNUSED(dummy)(__NPY_UNUSED_TAGGEDdummy) __attribute__ ((__unused__)), PyObject *args)
175{
176 PyUFuncObject *ufunc;
177 PyObject *str;
178 if (!PyArg_ParseTuple(args, "O!O!:_add_newdoc_ufunc", &PyUFunc_Type, &ufunc,
179 &PyUnicode_Type, &str)) {
180 return NULL((void*)0);
181 }
182 if (ufunc->doc != NULL((void*)0)) {
183 PyErr_SetString(PyExc_ValueError,
184 "Cannot change docstring of ufunc with non-NULL docstring");
185 return NULL((void*)0);
186 }
187
188 PyObject *tmp = PyUnicode_AsUTF8String(str);
189 if (tmp == NULL((void*)0)) {
190 return NULL((void*)0);
191 }
192 char *docstr = PyBytes_AS_STRING(tmp)(((void) (0)), (((PyBytesObject *)(tmp))->ob_sval));
193
194 /*
195 * This introduces a memory leak, as the memory allocated for the doc
196 * will not be freed even if the ufunc itself is deleted. In practice
197 * this should not be a problem since the user would have to
198 * repeatedly create, document, and throw away ufuncs.
199 */
200 char *newdocstr = malloc(strlen(docstr) + 1);
201 if (!newdocstr) {
202 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
203 return PyErr_NoMemory();
204 }
205 strcpy(newdocstr, docstr);
206 ufunc->doc = newdocstr;
207
208 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
209 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
210}
211
212
213/*
214 *****************************************************************************
215 ** SETUP UFUNCS **
216 *****************************************************************************
217 */
218
219NPY_VISIBILITY_HIDDEN__attribute__((visibility("hidden"))) PyObject *npy_um_str_array_prepare = NULL((void*)0);
220NPY_VISIBILITY_HIDDEN__attribute__((visibility("hidden"))) PyObject *npy_um_str_array_wrap = NULL((void*)0);
221NPY_VISIBILITY_HIDDEN__attribute__((visibility("hidden"))) PyObject *npy_um_str_pyvals_name = NULL((void*)0);
222
223/* intern some strings used in ufuncs, returns 0 on success */
224static int
225intern_strings(void)
226{
227 if (!(npy_um_str_array_prepare = PyUnicode_InternFromString("__array_prepare__"))) return -1;
228 if (!(npy_um_str_array_wrap = PyUnicode_InternFromString("__array_wrap__"))) return -1;
229 if (!(npy_um_str_pyvals_name = PyUnicode_InternFromString(UFUNC_PYVALS_NAME"UFUNC_PYVALS"))) return -1;
230 return 0;
231}
232
233/* Setup the umath part of the module */
234
235int initumath(PyObject *m)
236{
237 PyObject *d, *s, *s2;
238 int UFUNC_FLOATING_POINT_SUPPORT = 1;
239
240#ifdef NO_UFUNC_FLOATING_POINT_SUPPORT
241 UFUNC_FLOATING_POINT_SUPPORT = 0;
242#endif
243
244 /* Add some symbolic constants to the module */
245 d = PyModule_GetDict(m);
246
247 PyDict_SetItemString(d, "pi", s = PyFloat_FromDouble(NPY_PI3.141592653589793238462643383279502884));
248 Py_DECREF(s)_Py_DECREF(((PyObject*)(s)));
249 PyDict_SetItemString(d, "e", s = PyFloat_FromDouble(NPY_E2.718281828459045235360287471352662498));
250 Py_DECREF(s)_Py_DECREF(((PyObject*)(s)));
251 PyDict_SetItemString(d, "euler_gamma", s = PyFloat_FromDouble(NPY_EULER0.577215664901532860606512090082402431));
252 Py_DECREF(s)_Py_DECREF(((PyObject*)(s)));
253
254#define ADDCONST(str) PyModule_AddIntConstant(m, #str, UFUNC_##str)
255#define ADDSCONST(str) PyModule_AddStringConstant(m, "UFUNC_" #str, UFUNC_##str)
256
257 ADDCONST(ERR_IGNORE);
258 ADDCONST(ERR_WARN);
259 ADDCONST(ERR_CALL);
260 ADDCONST(ERR_RAISE);
261 ADDCONST(ERR_PRINT);
262 ADDCONST(ERR_LOG);
263 ADDCONST(ERR_DEFAULT);
264
265 ADDCONST(SHIFT_DIVIDEBYZERO);
266 ADDCONST(SHIFT_OVERFLOW);
267 ADDCONST(SHIFT_UNDERFLOW);
268 ADDCONST(SHIFT_INVALID);
269
270 ADDCONST(FPE_DIVIDEBYZERO);
271 ADDCONST(FPE_OVERFLOW);
272 ADDCONST(FPE_UNDERFLOW);
273 ADDCONST(FPE_INVALID);
274
275 ADDCONST(FLOATING_POINT_SUPPORT);
276
277 ADDSCONST(PYVALS_NAME);
278
279#undef ADDCONST
280#undef ADDSCONST
281 PyModule_AddIntConstant(m, "UFUNC_BUFSIZE_DEFAULT", (long)NPY_BUFSIZE8192);
282
283 PyModule_AddObject(m, "PINF", PyFloat_FromDouble(NPY_INFINITY((npy_double)__npy_inff())));
1
Calling 'PyFloat_FromDouble'
3
Returning from 'PyFloat_FromDouble'
4
PyObject ownership leak with reference count of 1
284 PyModule_AddObject(m, "NINF", PyFloat_FromDouble(-NPY_INFINITY((npy_double)__npy_inff())));
285 PyModule_AddObject(m, "PZERO", PyFloat_FromDouble(NPY_PZERO((npy_double)__npy_pzerof())));
286 PyModule_AddObject(m, "NZERO", PyFloat_FromDouble(NPY_NZERO((npy_double)__npy_nzerof())));
287 PyModule_AddObject(m, "NAN", PyFloat_FromDouble(NPY_NAN((npy_double)__npy_nanf())));
288
289 s = PyDict_GetItemString(d, "true_divide");
290 PyDict_SetItemString(d, "divide", s);
291
292 s = PyDict_GetItemString(d, "conjugate");
293 s2 = PyDict_GetItemString(d, "remainder");
294 /* Setup the array object's numerical structures with appropriate
295 ufuncs in d*/
296 _PyArray_SetNumericOps(d);
297
298 PyDict_SetItemString(d, "conj", s);
299 PyDict_SetItemString(d, "mod", s2);
300
301 if (intern_strings() < 0) {
302 PyErr_SetString(PyExc_RuntimeError,
303 "cannot intern umath strings while initializing _multiarray_umath.");
304 return -1;
305 }
306
307 return 0;
308}

/opt/pyrefcon/lib/pyrefcon/models/models/PyFloat_FromDouble.model

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