Bug Summary

File:_dispatcher.cpp
Warning:line 1001, column 5
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 _dispatcher.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 -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/numba/csa-scan,ctu-index-name=/tmp/pyrefcon/numba/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/numba/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/numba -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -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 -fdeprecated-macro -fdebug-compilation-dir=/tmp/pyrefcon/numba -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/numba/csa-scan/reports -x c++ numba/_dispatcher.cpp

numba/_dispatcher.cpp

1#include "_pymodule.h"
2
3#include <cstring>
4#include <ctime>
5#include <cassert>
6#include <vector>
7
8#include "_typeof.h"
9#include "frameobject.h"
10#include "core/typeconv/typeconv.hpp"
11#include "_devicearray.h"
12
13/*
14 * The following call_trace and call_trace_protected functions
15 * as well as the C_TRACE macro are taken from ceval.c
16 *
17 */
18
19static int
20call_trace(Py_tracefunc func, PyObject *obj,
21 PyThreadState *tstate, PyFrameObject *frame,
22 int what, PyObject *arg)
23{
24 int result;
25 if (tstate->tracing)
26 return 0;
27 tstate->tracing++;
28 tstate->use_tracing = 0;
29 result = func(obj, frame, what, arg);
30 tstate->use_tracing = ((tstate->c_tracefunc != NULL__null)
31 || (tstate->c_profilefunc != NULL__null));
32 tstate->tracing--;
33 return result;
34}
35
36static int
37call_trace_protected(Py_tracefunc func, PyObject *obj,
38 PyThreadState *tstate, PyFrameObject *frame,
39 int what, PyObject *arg)
40{
41 PyObject *type, *value, *traceback;
42 int err;
43 PyErr_Fetch(&type, &value, &traceback);
44 err = call_trace(func, obj, tstate, frame, what, arg);
45 if (err == 0)
46 {
47 PyErr_Restore(type, value, traceback);
48 return 0;
49 }
50 else
51 {
52 Py_XDECREF(type)_Py_XDECREF(((PyObject*)(type)));
53 Py_XDECREF(value)_Py_XDECREF(((PyObject*)(value)));
54 Py_XDECREF(traceback)_Py_XDECREF(((PyObject*)(traceback)));
55 return -1;
56 }
57}
58
59/*
60 * The original C_TRACE macro (from ceval.c) would call
61 * PyTrace_C_CALL et al., for which the frame argument wouldn't
62 * be usable. Since we explicitly synthesize a frame using the
63 * original Python code object, we call PyTrace_CALL instead so
64 * the profiler can report the correct source location.
65 *
66 * Likewise, while ceval.c would call PyTrace_C_EXCEPTION in case
67 * of error, the profiler would simply expect a RETURN in case of
68 * a Python function, so we generate that here (making sure the
69 * exception state is preserved correctly).
70 */
71#define C_TRACE(x, call)if (call_trace(tstate->c_profilefunc, tstate->c_profileobj
, tstate, tstate->frame, 0, cfunc)) x = __null; else { x =
call; if (tstate->c_profilefunc != __null) { if (x == __null
) { call_trace_protected(tstate->c_profilefunc, tstate->
c_profileobj, tstate, tstate->frame, 3, cfunc); } else { if
(call_trace(tstate->c_profilefunc, tstate->c_profileobj
, tstate, tstate->frame, 3, cfunc)) { _Py_DECREF(((PyObject
*)(x))); x = __null; } } } }
\
72if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \
73 tstate, tstate->frame, PyTrace_CALL0, cfunc)) \
74 x = NULL__null; \
75else \
76{ \
77 x = call; \
78 if (tstate->c_profilefunc != NULL__null) \
79 { \
80 if (x == NULL__null) \
81 { \
82 call_trace_protected(tstate->c_profilefunc, \
83 tstate->c_profileobj, \
84 tstate, tstate->frame, \
85 PyTrace_RETURN3, cfunc); \
86 /* XXX should pass (type, value, tb) */ \
87 } \
88 else \
89 { \
90 if (call_trace(tstate->c_profilefunc, \
91 tstate->c_profileobj, \
92 tstate, tstate->frame, \
93 PyTrace_RETURN3, cfunc)) \
94 { \
95 Py_DECREF(x)_Py_DECREF(((PyObject*)(x))); \
96 x = NULL__null; \
97 } \
98 } \
99 } \
100}
101
102typedef std::vector<Type> TypeTable;
103typedef std::vector<PyObject*> Functions;
104
105/* The Dispatcher class is the base class of all dispatchers in the CPU and
106 CUDA targets. Its main responsibilities are:
107
108 - Resolving the best overload to call for a given set of arguments, and
109 - Calling the resolved overload.
110
111 This logic is implemented within this class for efficiency (lookup of the
112 appropriate overload needs to be fast) and ease of implementation (calling
113 directly into a compiled function using a function pointer is easier within
114 the C++ code where the overload has been resolved). */
115class Dispatcher {
116public:
117 PyObject_HEADPyObject ob_base;
118 /* Whether compilation of new overloads is permitted */
119 char can_compile;
120 /* Whether fallback to object mode is permitted */
121 char can_fallback;
122 /* Whether types must match exactly when resolving overloads.
123 If not, conversions (e.g. float32 -> float64) are permitted when
124 searching for a match. */
125 char exact_match_required;
126 /* Borrowed reference */
127 PyObject *fallbackdef;
128 /* Whether to fold named arguments and default values
129 (false for lifted loops) */
130 int fold_args;
131 /* Whether the last positional argument is a stararg */
132 int has_stararg;
133 /* Tuple of argument names */
134 PyObject *argnames;
135 /* Tuple of default values */
136 PyObject *defargs;
137 /* Number of arguments to function */
138 int argct;
139 /* Used for selecting overloaded function implementations */
140 TypeManager *tm;
141 /* An array of overloads */
142 Functions functions;
143 /* A flattened array of argument types to all overloads
144 * (invariant: sizeof(overloads) == argct * sizeof(functions)) */
145 TypeTable overloads;
146
147 /* Add a new overload. Parameters:
148
149 - args: An array of Type objects, one for each parameter
150 - callable: The callable implementing this overload. */
151 void addDefinition(Type args[], PyObject *callable) {
152 overloads.reserve(argct + overloads.size());
153 for (int i=0; i<argct; ++i) {
154 overloads.push_back(args[i]);
155 }
156 functions.push_back(callable);
157 }
158
159 /* Given a list of types, find the overloads that have a matching signature.
160 Returns the best match, as well as the number of matches found.
161
162 Parameters:
163
164 - sig: an array of Type objects, one for each parameter.
165 - matches: the number of matches found (mutated by this function).
166 - allow_unsafe: whether to match overloads that would require an unsafe
167 cast.
168 - exact_match_required: Whether all arguments types must match the
169 overload's types exactly. When false,
170 overloads that would require a type conversion
171 can also be matched. */
172 PyObject* resolve(Type sig[], int &matches, bool allow_unsafe,
173 bool exact_match_required) const {
174 const int ovct = functions.size();
175 int selected;
176 matches = 0;
177 if (0 == ovct) {
178 // No overloads registered
179 return NULL__null;
180 }
181 if (argct == 0) {
182 // Nullary function: trivial match on first overload
183 matches = 1;
184 selected = 0;
185 }
186 else {
187 matches = tm->selectOverload(sig, &overloads[0], selected, argct,
188 ovct, allow_unsafe,
189 exact_match_required);
190 }
191 if (matches == 1) {
192 return functions[selected];
193 }
194 return NULL__null;
195 }
196
197 /* Remove all overloads */
198 void clear() {
199 functions.clear();
200 overloads.clear();
201 }
202
203};
204
205
206static int
207Dispatcher_traverse(Dispatcher *self, visitproc visit, void *arg)
208{
209 Py_VISIT(self->defargs)do { if (self->defargs) { int vret = visit(((PyObject*)(self
->defargs)), arg); if (vret) return vret; } } while (0)
;
210 return 0;
211}
212
213static void
214Dispatcher_dealloc(Dispatcher *self)
215{
216 Py_XDECREF(self->argnames)_Py_XDECREF(((PyObject*)(self->argnames)));
217 Py_XDECREF(self->defargs)_Py_XDECREF(((PyObject*)(self->defargs)));
218 self->clear();
219 Py_TYPE(self)(((PyObject*)(self))->ob_type)->tp_free((PyObject*)self);
220}
221
222
223static int
224Dispatcher_init(Dispatcher *self, PyObject *args, PyObject *kwds)
225{
226 PyObject *tmaddrobj;
227 void *tmaddr;
228 int argct;
229 int can_fallback;
230 int has_stararg = 0;
231 int exact_match_required = 0;
232
233 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "OiiO!O!i|ii", &tmaddrobj, &argct,
234 &self->fold_args,
235 &PyTuple_Type, &self->argnames,
236 &PyTuple_Type, &self->defargs,
237 &can_fallback,
238 &has_stararg,
239 &exact_match_required
240 )) {
241 return -1;
242 }
243 Py_INCREF(self->argnames)_Py_INCREF(((PyObject*)(self->argnames)));
244 Py_INCREF(self->defargs)_Py_INCREF(((PyObject*)(self->defargs)));
245 tmaddr = PyLong_AsVoidPtr(tmaddrobj);
246 self->tm = static_cast<TypeManager*>(tmaddr);
247 self->argct = argct;
248 self->can_compile = 1;
249 self->can_fallback = can_fallback;
250 self->fallbackdef = NULL__null;
251 self->has_stararg = has_stararg;
252 self->exact_match_required = exact_match_required;
253 return 0;
254}
255
256static PyObject *
257Dispatcher_clear(Dispatcher *self, PyObject *args)
258{
259 self->clear();
260 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
261}
262
263static
264PyObject*
265Dispatcher_Insert(Dispatcher *self, PyObject *args, PyObject *kwds)
266{
267 /* The cuda kwarg is a temporary addition until CUDA overloads are compiled
268 * functions. Once they are compiled functions, kwargs can be removed from
269 * this function. */
270 static char *keywords[] = {
271 (char*)"sig",
272 (char*)"func",
273 (char*)"objectmode",
274 (char*)"cuda",
275 NULL__null
276 };
277
278 PyObject *sigtup, *cfunc;
279 int i, sigsz;
280 int *sig;
281 int objectmode = 0;
282 int cuda = 0;
283
284 if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwds, "OO|ip", keywords, &sigtup,
285 &cfunc, &objectmode, &cuda)) {
286 return NULL__null;
287 }
288
289 if (!cuda && !PyObject_TypeCheck(cfunc, &PyCFunction_Type)((((PyObject*)(cfunc))->ob_type) == (&PyCFunction_Type
) || PyType_IsSubtype((((PyObject*)(cfunc))->ob_type), (&
PyCFunction_Type)))
) {
290 PyErr_SetString(PyExc_TypeError, "must be builtin_function_or_method");
291 return NULL__null;
292 }
293
294 sigsz = PySequence_Fast_GET_SIZE(sigtup)(((((((PyObject*)(sigtup))->ob_type))->tp_flags & (
(1UL << 25))) != 0) ? ((static_cast<void> (0)), (
((PyVarObject*)(sigtup))->ob_size)) : (((PyVarObject*)(((static_cast
<void> (0)), (PyTupleObject *)(sigtup))))->ob_size))
;
295 sig = new int[sigsz];
296
297 for (i = 0; i < sigsz; ++i) {
298 sig[i] = PyLong_AsLong(PySequence_Fast_GET_ITEM(sigtup, i)(((((((PyObject*)(sigtup))->ob_type))->tp_flags & (
(1UL << 25))) != 0) ? (((PyListObject *)(sigtup))->ob_item
[i]) : (((static_cast<void> (0)), (PyTupleObject *)(sigtup
))->ob_item[i]))
);
299 }
300
301 /* The reference to cfunc is borrowed; this only works because the
302 derived Python class also stores an (owned) reference to cfunc. */
303 self->addDefinition(sig, cfunc);
304
305 /* Add pure python fallback */
306 if (!self->fallbackdef && objectmode){
307 self->fallbackdef = cfunc;
308 }
309
310 delete[] sig;
311
312 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
313}
314
315static
316void explain_issue(PyObject *dispatcher, PyObject *args, PyObject *kws,
317 const char *method_name, const char *default_msg)
318{
319 PyObject *callback, *result;
320 callback = PyObject_GetAttrString(dispatcher, method_name);
321 if (!callback) {
322 PyErr_SetString(PyExc_TypeError, default_msg);
323 return;
324 }
325 result = PyObject_Call(callback, args, kws);
326 Py_DECREF(callback)_Py_DECREF(((PyObject*)(callback)));
327 if (result != NULL__null) {
328 PyErr_Format(PyExc_RuntimeError, "%s must raise an exception",
329 method_name);
330 Py_DECREF(result)_Py_DECREF(((PyObject*)(result)));
331 }
332}
333
334static
335void explain_ambiguous(PyObject *dispatcher, PyObject *args, PyObject *kws)
336{
337 explain_issue(dispatcher, args, kws, "_explain_ambiguous",
338 "Ambiguous overloading");
339}
340
341static
342void explain_matching_error(PyObject *dispatcher, PyObject *args, PyObject *kws)
343{
344 explain_issue(dispatcher, args, kws, "_explain_matching_error",
345 "No matching definition");
346}
347
348static
349int search_new_conversions(PyObject *dispatcher, PyObject *args, PyObject *kws)
350{
351 PyObject *callback, *result;
352 int res;
353
354 callback = PyObject_GetAttrString(dispatcher,
355 "_search_new_conversions");
356 if (!callback) {
357 return -1;
358 }
359 result = PyObject_Call(callback, args, kws);
360 Py_DECREF(callback)_Py_DECREF(((PyObject*)(callback)));
361 if (result == NULL__null) {
362 return -1;
363 }
364 if (!PyBool_Check(result)((((PyObject*)(result))->ob_type) == &PyBool_Type)) {
365 Py_DECREF(result)_Py_DECREF(((PyObject*)(result)));
366 PyErr_SetString(PyExc_TypeError,
367 "_search_new_conversions() should return a boolean");
368 return -1;
369 }
370 res = (result == Py_True((PyObject *) &_Py_TrueStruct)) ? 1 : 0;
371 Py_DECREF(result)_Py_DECREF(((PyObject*)(result)));
372 return res;
373}
374
375/* A custom, fast, inlinable version of PyCFunction_Call() */
376static PyObject *
377call_cfunc(Dispatcher *self, PyObject *cfunc, PyObject *args, PyObject *kws, PyObject *locals)
378{
379 PyCFunctionWithKeywords fn;
380 PyThreadState *tstate;
381
382 assert(PyCFunction_Check(cfunc))(static_cast<void> (0));
383 assert(PyCFunction_GET_FLAGS(cfunc) == METH_VARARGS | METH_KEYWORDS)(static_cast<void> (0));
384 fn = (PyCFunctionWithKeywords) PyCFunction_GET_FUNCTION(cfunc)(((PyCFunctionObject *)cfunc) -> m_ml -> ml_meth);
385 tstate = PyThreadState_GET()PyThreadState_Get();
386
387 if (tstate->use_tracing && tstate->c_profilefunc)
388 {
389 /*
390 * The following code requires some explaining:
391 *
392 * We want the jit-compiled function to be visible to the profiler, so we
393 * need to synthesize a frame for it.
394 * The PyFrame_New() constructor doesn't do anything with the 'locals' value if the 'code's
395 * 'CO_NEWLOCALS' flag is set (which is always the case nowadays).
396 * So, to get local variables into the frame, we have to manually set the 'f_locals'
397 * member, then call `PyFrame_LocalsToFast`, where a subsequent call to the `frame.f_locals`
398 * property (by virtue of the `frame_getlocals` function in frameobject.c) will find them.
399 */
400 PyCodeObject *code = (PyCodeObject*)PyObject_GetAttrString((PyObject*)self, "__code__");
401 PyObject *globals = PyDict_New();
402 PyObject *builtins = PyEval_GetBuiltins();
403 PyFrameObject *frame = NULL__null;
404 PyObject *result = NULL__null;
405
406 if (!code) {
407 PyErr_Format(PyExc_RuntimeError, "No __code__ attribute found.");
408 goto error;
409 }
410 /* Populate builtins, which is required by some JITted functions */
411 if (PyDict_SetItemString(globals, "__builtins__", builtins)) {
412 goto error;
413 }
414
415 /* unset the CO_OPTIMIZED flag, make the frame get a new locals dict */
416 code->co_flags &= 0xFFFE;
417
418 frame = PyFrame_New(tstate, code, globals, locals);
419 if (frame == NULL__null) {
420 goto error;
421 }
422 /* Populate the 'fast locals' in `frame` */
423 PyFrame_LocalsToFast(frame, 0);
424 tstate->frame = frame;
425 C_TRACE(result, fn(PyCFunction_GET_SELF(cfunc), args, kws))if (call_trace(tstate->c_profilefunc, tstate->c_profileobj
, tstate, tstate->frame, 0, cfunc)) result = __null; else {
result = fn((((PyCFunctionObject *)cfunc) -> m_ml -> ml_flags
& 0x0020 ? __null : ((PyCFunctionObject *)cfunc) -> m_self
), args, kws); if (tstate->c_profilefunc != __null) { if (
result == __null) { call_trace_protected(tstate->c_profilefunc
, tstate->c_profileobj, tstate, tstate->frame, 3, cfunc
); } else { if (call_trace(tstate->c_profilefunc, tstate->
c_profileobj, tstate, tstate->frame, 3, cfunc)) { _Py_DECREF
(((PyObject*)(result))); result = __null; } } } }
;
426 /* write changes back to locals? */
427 PyFrame_FastToLocals(frame);
428 tstate->frame = frame->f_back;
429
430 error:
431 Py_XDECREF(frame)_Py_XDECREF(((PyObject*)(frame)));
432 Py_XDECREF(globals)_Py_XDECREF(((PyObject*)(globals)));
433 Py_XDECREF(code)_Py_XDECREF(((PyObject*)(code)));
434 return result;
435 }
436 else
437 return fn(PyCFunction_GET_SELF(cfunc)(((PyCFunctionObject *)cfunc) -> m_ml -> ml_flags &
0x0020 ? __null : ((PyCFunctionObject *)cfunc) -> m_self)
, args, kws);
438}
439
440static
441PyObject*
442compile_and_invoke(Dispatcher *self, PyObject *args, PyObject *kws, PyObject *locals)
443{
444 /* Compile a new one */
445 PyObject *cfa, *cfunc, *retval;
446 cfa = PyObject_GetAttrString((PyObject*)self, "_compile_for_args");
447 if (cfa == NULL__null)
448 return NULL__null;
449
450 /* NOTE: we call the compiled function ourselves instead of
451 letting the Python derived class do it. This is for proper
452 behaviour of globals() in jitted functions (issue #476). */
453 cfunc = PyObject_Call(cfa, args, kws);
454 Py_DECREF(cfa)_Py_DECREF(((PyObject*)(cfa)));
455
456 if (cfunc == NULL__null)
457 return NULL__null;
458
459 if (PyObject_TypeCheck(cfunc, &PyCFunction_Type)((((PyObject*)(cfunc))->ob_type) == (&PyCFunction_Type
) || PyType_IsSubtype((((PyObject*)(cfunc))->ob_type), (&
PyCFunction_Type)))
) {
460 retval = call_cfunc(self, cfunc, args, kws, locals);
461 } else {
462 /* Re-enter interpreter */
463 retval = PyObject_Call(cfunc, args, kws);
464 }
465 Py_DECREF(cfunc)_Py_DECREF(((PyObject*)(cfunc)));
466
467 return retval;
468}
469
470/* A copy of compile_and_invoke, that only compiles. This is needed for CUDA
471 * kernels, because its overloads are Python instances of the _Kernel class,
472 * rather than compiled functions. Once CUDA overloads are compiled functions,
473 * cuda_compile_only can be removed. */
474static
475PyObject*
476cuda_compile_only(Dispatcher *self, PyObject *args, PyObject *kws, PyObject *locals)
477{
478 /* Compile a new one */
479 PyObject *cfa, *cfunc;
480 cfa = PyObject_GetAttrString((PyObject*)self, "_compile_for_args");
481 if (cfa == NULL__null)
482 return NULL__null;
483
484 cfunc = PyObject_Call(cfa, args, kws);
485 Py_DECREF(cfa)_Py_DECREF(((PyObject*)(cfa)));
486
487 return cfunc;
488}
489
490static int
491find_named_args(Dispatcher *self, PyObject **pargs, PyObject **pkws)
492{
493 PyObject *oldargs = *pargs, *newargs;
494 PyObject *kws = *pkws;
495 Py_ssize_t pos_args = PyTuple_GET_SIZE(oldargs)(((PyVarObject*)(((static_cast<void> (0)), (PyTupleObject
*)(oldargs))))->ob_size)
;
496 Py_ssize_t named_args, total_args, i;
497 Py_ssize_t func_args = PyTuple_GET_SIZE(self->argnames)(((PyVarObject*)(((static_cast<void> (0)), (PyTupleObject
*)(self->argnames))))->ob_size)
;
498 Py_ssize_t defaults = PyTuple_GET_SIZE(self->defargs)(((PyVarObject*)(((static_cast<void> (0)), (PyTupleObject
*)(self->defargs))))->ob_size)
;
499 /* Last parameter with a default value */
500 Py_ssize_t last_def = (self->has_stararg)
501 ? func_args - 2
502 : func_args - 1;
503 /* First parameter with a default value */
504 Py_ssize_t first_def = last_def - defaults + 1;
505 /* Minimum number of required arguments */
506 Py_ssize_t minargs = first_def;
507
508 if (kws != NULL__null)
509 named_args = PyDict_Size(kws);
510 else
511 named_args = 0;
512 total_args = pos_args + named_args;
513 if (!self->has_stararg && total_args > func_args) {
514 PyErr_Format(PyExc_TypeError,
515 "too many arguments: expected %d, got %d",
516 (int) func_args, (int) total_args);
517 return -1;
518 }
519 else if (total_args < minargs) {
520 if (minargs == func_args)
521 PyErr_Format(PyExc_TypeError,
522 "not enough arguments: expected %d, got %d",
523 (int) minargs, (int) total_args);
524 else
525 PyErr_Format(PyExc_TypeError,
526 "not enough arguments: expected at least %d, got %d",
527 (int) minargs, (int) total_args);
528 return -1;
529 }
530 newargs = PyTuple_New(func_args);
531 if (!newargs)
532 return -1;
533 /* First pack the stararg */
534 if (self->has_stararg) {
535 Py_ssize_t stararg_size = Py_MAX(0, pos_args - func_args + 1)(((0) > (pos_args - func_args + 1)) ? (0) : (pos_args - func_args
+ 1))
;
536 PyObject *stararg = PyTuple_New(stararg_size);
537 if (!stararg) {
538 Py_DECREF(newargs)_Py_DECREF(((PyObject*)(newargs)));
539 return -1;
540 }
541 for (i = 0; i < stararg_size; i++) {
542 PyObject *value = PyTuple_GET_ITEM(oldargs, func_args - 1 + i)(((static_cast<void> (0)), (PyTupleObject *)(oldargs))->
ob_item[func_args - 1 + i])
;
543 Py_INCREF(value)_Py_INCREF(((PyObject*)(value)));
544 PyTuple_SET_ITEM(stararg, i, value)PyTuple_SetItem(stararg, i, value);
545 }
546 /* Put it in last position */
547 PyTuple_SET_ITEM(newargs, func_args - 1, stararg)PyTuple_SetItem(newargs, func_args - 1, stararg);
548
549 }
550 for (i = 0; i < pos_args; i++) {
551 PyObject *value = PyTuple_GET_ITEM(oldargs, i)(((static_cast<void> (0)), (PyTupleObject *)(oldargs))->
ob_item[i])
;
552 if (self->has_stararg && i >= func_args - 1) {
553 /* Skip stararg */
554 break;
555 }
556 Py_INCREF(value)_Py_INCREF(((PyObject*)(value)));
557 PyTuple_SET_ITEM(newargs, i, value)PyTuple_SetItem(newargs, i, value);
558 }
559
560 /* Iterate over missing positional arguments, try to find them in
561 named arguments or default values. */
562 for (i = pos_args; i < func_args; i++) {
563 PyObject *name = PyTuple_GET_ITEM(self->argnames, i)(((static_cast<void> (0)), (PyTupleObject *)(self->argnames
))->ob_item[i])
;
564 if (self->has_stararg && i >= func_args - 1) {
565 /* Skip stararg */
566 break;
567 }
568 if (kws != NULL__null) {
569 /* Named argument? */
570 PyObject *value = PyDict_GetItem(kws, name);
571 if (value != NULL__null) {
572 Py_INCREF(value)_Py_INCREF(((PyObject*)(value)));
573 PyTuple_SET_ITEM(newargs, i, value)PyTuple_SetItem(newargs, i, value);
574 named_args--;
575 continue;
576 }
577 }
578 if (i >= first_def && i <= last_def) {
579 /* Argument has a default value? */
580 PyObject *value = PyTuple_GET_ITEM(self->defargs, i - first_def)(((static_cast<void> (0)), (PyTupleObject *)(self->defargs
))->ob_item[i - first_def])
;
581 Py_INCREF(value)_Py_INCREF(((PyObject*)(value)));
582 PyTuple_SET_ITEM(newargs, i, value)PyTuple_SetItem(newargs, i, value);
583 continue;
584 }
585 else if (i < func_args - 1 || !self->has_stararg) {
586 PyErr_Format(PyExc_TypeError,
587 "missing argument '%s'",
588 PyString_AsStringPyUnicode_AsUTF8(name));
589 Py_DECREF(newargs)_Py_DECREF(((PyObject*)(newargs)));
590 return -1;
591 }
592 }
593 if (named_args) {
594 PyErr_Format(PyExc_TypeError,
595 "some keyword arguments unexpected");
596 Py_DECREF(newargs)_Py_DECREF(((PyObject*)(newargs)));
597 return -1;
598 }
599 *pargs = newargs;
600 *pkws = NULL__null;
601 return 0;
602}
603
604
605/*
606 * Management of thread-local
607 */
608
609#ifdef _MSC_VER
610#define THREAD_LOCAL(ty)__thread ty __declspec(thread) ty
611#else
612/* Non-standard C99 extension that's understood by gcc and clang */
613#define THREAD_LOCAL(ty)__thread ty __thread ty
614#endif
615
616static THREAD_LOCAL(bool)__thread bool use_tls_target_stack;
617
618
619struct raii_use_tls_target_stack {
620 bool old_setting;
621
622 raii_use_tls_target_stack(bool new_setting)
623 : old_setting(use_tls_target_stack)
624 {
625 use_tls_target_stack = new_setting;
626 }
627
628 ~raii_use_tls_target_stack() {
629 use_tls_target_stack = old_setting;
630 }
631};
632
633static PyObject*
634Dispatcher_call(Dispatcher *self, PyObject *args, PyObject *kws)
635{
636 PyObject *tmptype, *retval = NULL__null;
637 int *tys = NULL__null;
638 int argct;
639 int i;
640 int prealloc[24];
641 int matches;
642 PyObject *cfunc;
643 PyThreadState *ts = PyThreadState_Get();
644 PyObject *locals = NULL__null;
645
646 // Check TLS target stack
647 if (use_tls_target_stack) {
648 raii_use_tls_target_stack turn_off(false);
649 PyObject * meth_call_tls_target;
650 meth_call_tls_target = PyObject_GetAttrString((PyObject*)self,
651 "_call_tls_target");
652 if (!meth_call_tls_target) return NULL__null;
653 // Transfer control to self._call_tls_target
654 retval = PyObject_Call(meth_call_tls_target, args, kws);
655 Py_DECREF(meth_call_tls_target)_Py_DECREF(((PyObject*)(meth_call_tls_target)));
656 return retval;
657 }
658
659 /* If compilation is enabled, ensure that an exact match is found and if
660 * not compile one */
661 int exact_match_required = self->can_compile ? 1 : self->exact_match_required;
662
663 if (ts->use_tracing && ts->c_profilefunc) {
664 locals = PyEval_GetLocals();
665 if (locals == NULL__null) {
666 goto CLEANUP;
667 }
668 }
669 if (self->fold_args) {
670 if (find_named_args(self, &args, &kws))
671 return NULL__null;
672 }
673 else
674 Py_INCREF(args)_Py_INCREF(((PyObject*)(args)));
675 /* Now we own a reference to args */
676
677 argct = PySequence_Fast_GET_SIZE(args)(((((((PyObject*)(args))->ob_type))->tp_flags & ((1UL
<< 25))) != 0) ? ((static_cast<void> (0)), (((PyVarObject
*)(args))->ob_size)) : (((PyVarObject*)(((static_cast<void
> (0)), (PyTupleObject *)(args))))->ob_size))
;
678
679 if (argct < (Py_ssize_t) (sizeof(prealloc) / sizeof(int)))
680 tys = prealloc;
681 else
682 tys = new int[argct];
683
684 for (i = 0; i < argct; ++i) {
685 tmptype = PySequence_Fast_GET_ITEM(args, i)(((((((PyObject*)(args))->ob_type))->tp_flags & ((1UL
<< 25))) != 0) ? (((PyListObject *)(args))->ob_item
[i]) : (((static_cast<void> (0)), (PyTupleObject *)(args
))->ob_item[i]))
;
686 tys[i] = typeof_typecode((PyObject *) self, tmptype);
687 if (tys[i] == -1) {
688 if (self->can_fallback){
689 /* We will clear the exception if fallback is allowed. */
690 PyErr_Clear();
691 } else {
692 goto CLEANUP;
693 }
694 }
695 }
696
697 /* We only allow unsafe conversions if compilation of new specializations
698 has been disabled.
699
700 Note that the number of matches is returned in matches by resolve, which
701 accepts it as a reference. */
702 cfunc = self->resolve(tys, matches, !self->can_compile,
703 exact_match_required);
704
705 if (matches == 0 && !self->can_compile) {
706 /*
707 * If we can't compile a new specialization, look for
708 * matching signatures for which conversions haven't been
709 * registered on the C++ TypeManager.
710 */
711 int res = search_new_conversions((PyObject *) self, args, kws);
712 if (res < 0) {
713 retval = NULL__null;
714 goto CLEANUP;
715 }
716 if (res > 0) {
717 /* Retry with the newly registered conversions */
718 cfunc = self->resolve(tys, matches, !self->can_compile,
719 exact_match_required);
720 }
721 }
722 if (matches == 1) {
723 /* Definition is found */
724 retval = call_cfunc(self, cfunc, args, kws, locals);
725 } else if (matches == 0) {
726 /* No matching definition */
727 if (self->can_compile) {
728 retval = compile_and_invoke(self, args, kws, locals);
729 } else if (self->fallbackdef) {
730 /* Have object fallback */
731 retval = call_cfunc(self, self->fallbackdef, args, kws, locals);
732 } else {
733 /* Raise TypeError */
734 explain_matching_error((PyObject *) self, args, kws);
735 retval = NULL__null;
736 }
737 } else if (self->can_compile) {
738 /* Ambiguous, but are allowed to compile */
739 retval = compile_and_invoke(self, args, kws, locals);
740 } else {
741 /* Ambiguous */
742 explain_ambiguous((PyObject *) self, args, kws);
743 retval = NULL__null;
744 }
745
746CLEANUP:
747 if (tys != prealloc)
748 delete[] tys;
749 Py_DECREF(args)_Py_DECREF(((PyObject*)(args)));
750
751 return retval;
752}
753
754/* Based on Dispatcher_call above, with the following differences:
755 1. It does not invoke the definition of the function.
756 2. It returns the definition, instead of a value returned by the function.
757
758 This is because CUDA functions are, at present, _Kernel objects rather than
759 compiled functions. */
760static PyObject*
761Dispatcher_cuda_call(Dispatcher *self, PyObject *args, PyObject *kws)
762{
763 PyObject *tmptype, *retval = NULL__null;
764 int *tys = NULL__null;
765 int argct;
766 int i;
767 int prealloc[24];
768 int matches;
769 PyObject *cfunc;
770 PyThreadState *ts = PyThreadState_Get();
771 PyObject *locals = NULL__null;
772
773 /* If compilation is enabled, ensure that an exact match is found and if
774 * not compile one */
775 int exact_match_required = self->can_compile ? 1 : self->exact_match_required;
776
777 if (ts->use_tracing && ts->c_profilefunc) {
778 locals = PyEval_GetLocals();
779 if (locals == NULL__null) {
780 goto CLEANUP;
781 }
782 }
783 if (self->fold_args) {
784 if (find_named_args(self, &args, &kws))
785 return NULL__null;
786 }
787 else
788 Py_INCREF(args)_Py_INCREF(((PyObject*)(args)));
789 /* Now we own a reference to args */
790
791 argct = PySequence_Fast_GET_SIZE(args)(((((((PyObject*)(args))->ob_type))->tp_flags & ((1UL
<< 25))) != 0) ? ((static_cast<void> (0)), (((PyVarObject
*)(args))->ob_size)) : (((PyVarObject*)(((static_cast<void
> (0)), (PyTupleObject *)(args))))->ob_size))
;
792
793 if (argct < (Py_ssize_t) (sizeof(prealloc) / sizeof(int)))
794 tys = prealloc;
795 else
796 tys = new int[argct];
797
798 for (i = 0; i < argct; ++i) {
799 tmptype = PySequence_Fast_GET_ITEM(args, i)(((((((PyObject*)(args))->ob_type))->tp_flags & ((1UL
<< 25))) != 0) ? (((PyListObject *)(args))->ob_item
[i]) : (((static_cast<void> (0)), (PyTupleObject *)(args
))->ob_item[i]))
;
800 tys[i] = typeof_typecode((PyObject *) self, tmptype);
801 if (tys[i] == -1) {
802 if (self->can_fallback){
803 /* We will clear the exception if fallback is allowed. */
804 PyErr_Clear();
805 } else {
806 goto CLEANUP;
807 }
808 }
809 }
810
811 /* We only allow unsafe conversions if compilation of new specializations
812 has been disabled. */
813 cfunc = self->resolve(tys, matches, !self->can_compile,
814 exact_match_required);
815
816 if (matches == 0 && !self->can_compile) {
817 /*
818 * If we can't compile a new specialization, look for
819 * matching signatures for which conversions haven't been
820 * registered on the C++ TypeManager.
821 */
822 int res = search_new_conversions((PyObject *) self, args, kws);
823 if (res < 0) {
824 retval = NULL__null;
825 goto CLEANUP;
826 }
827 if (res > 0) {
828 /* Retry with the newly registered conversions */
829 cfunc = self->resolve(tys, matches, !self->can_compile,
830 exact_match_required);
831 }
832 }
833
834 if (matches == 1) {
835 /* Definition is found */
836 retval = cfunc;
837 Py_INCREF(retval)_Py_INCREF(((PyObject*)(retval)));
838 } else if (matches == 0) {
839 /* No matching definition */
840 if (self->can_compile) {
841 retval = cuda_compile_only(self, args, kws, locals);
842 } else if (self->fallbackdef) {
843 /* Have object fallback */
844 retval = call_cfunc(self, self->fallbackdef, args, kws, locals);
845 } else {
846 /* Raise TypeError */
847 explain_matching_error((PyObject *) self, args, kws);
848 retval = NULL__null;
849 }
850 } else if (self->can_compile) {
851 /* Ambiguous, but are allowed to compile */
852 retval = cuda_compile_only(self, args, kws, locals);
853 } else {
854 /* Ambiguous */
855 explain_ambiguous((PyObject *) self, args, kws);
856 retval = NULL__null;
857 }
858
859CLEANUP:
860 if (tys != prealloc)
861 delete[] tys;
862 Py_DECREF(args)_Py_DECREF(((PyObject*)(args)));
863
864 return retval;
865}
866
867static int
868import_devicearray(void)
869{
870 PyObject *devicearray = PyImport_ImportModule("numba._devicearray");
871 if (devicearray == NULL__null) {
872 return -1;
873 }
874 Py_DECREF(devicearray)_Py_DECREF(((PyObject*)(devicearray)));
875
876 DeviceArray_API = (void**)PyCapsule_Import("numba._devicearray._DEVICEARRAY_API", 0);
877 if (DeviceArray_API == NULL__null) {
878 return -1;
879 }
880
881 return 0;
882}
883
884static PyMethodDef Dispatcher_methods[] = {
885 { "_clear", (PyCFunction)Dispatcher_clear, METH_NOARGS0x0004, NULL__null },
886 { "_insert", (PyCFunction)Dispatcher_Insert, METH_VARARGS0x0001 | METH_KEYWORDS0x0002,
887 "insert new definition"},
888 { "_cuda_call", (PyCFunction)Dispatcher_cuda_call,
889 METH_VARARGS0x0001 | METH_KEYWORDS0x0002, "CUDA call resolution" },
890 { NULL__null },
891};
892
893static PyMemberDef Dispatcher_members[] = {
894 {(char*)"_can_compile", T_BOOL14, offsetof(Dispatcher, can_compile)__builtin_offsetof(Dispatcher, can_compile), 0, NULL__null },
895 {NULL__null} /* Sentinel */
896};
897
898
899static PyTypeObject DispatcherType = {
900 PyVarObject_HEAD_INIT(NULL, 0){ { 1, __null }, 0 },
901 "_dispatcher.Dispatcher", /* tp_name */
902 sizeof(Dispatcher), /* tp_basicsize */
903 0, /* tp_itemsize */
904 (destructor)Dispatcher_dealloc, /* tp_dealloc */
905 0, /* tp_print */
906 0, /* tp_getattr */
907 0, /* tp_setattr */
908 0, /* tp_compare */
909 0, /* tp_repr */
910 0, /* tp_as_number */
911 0, /* tp_as_sequence */
912 0, /* tp_as_mapping */
913 0, /* tp_hash */
914 (PyCFunctionWithKeywords)Dispatcher_call, /* tp_call*/
915 0, /* tp_str*/
916 0, /* tp_getattro*/
917 0, /* tp_setattro*/
918 0, /* tp_as_buffer*/
919 Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0) | Py_TPFLAGS_BASETYPE(1UL << 10) | Py_TPFLAGS_HAVE_GC(1UL << 14), /* tp_flags*/
920 "Dispatcher object", /* tp_doc */
921 (traverseproc) Dispatcher_traverse, /* tp_traverse */
922 0, /* tp_clear */
923 0, /* tp_richcompare */
924 0, /* tp_weaklistoffset */
925 0, /* tp_iter */
926 0, /* tp_iternext */
927 Dispatcher_methods, /* tp_methods */
928 Dispatcher_members, /* tp_members */
929 0, /* tp_getset */
930 0, /* tp_base */
931 0, /* tp_dict */
932 0, /* tp_descr_get */
933 0, /* tp_descr_set */
934 0, /* tp_dictoffset */
935 (initproc)Dispatcher_init, /* tp_init */
936 0, /* tp_alloc */
937 0, /* tp_new */
938 0, /* tp_free */
939 0, /* tp_is_gc */
940 0, /* tp_bases */
941 0, /* tp_mro */
942 0, /* tp_cache */
943 0, /* tp_subclasses */
944 0, /* tp_weaklist */
945 0, /* tp_del */
946 0, /* tp_version_tag */
947 0, /* tp_finalize */
948#if PY_MAJOR_VERSION3 == 3
949/* Python 3.8 has two slots, 3.9 has one. */
950#if PY_MINOR_VERSION8 > 7
951 0, /* tp_vectorcall */
952#if PY_MINOR_VERSION8 == 8
953 0, /* tp_print */
954#endif
955#endif
956#endif
957};
958
959
960static PyObject *compute_fingerprint(PyObject *self, PyObject *args)
961{
962 PyObject *val;
963 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O:compute_fingerprint", &val))
964 return NULL__null;
965 return typeof_compute_fingerprint(val);
966}
967
968static PyObject *set_use_tls_target_stack(PyObject *self, PyObject *args)
969{
970 int val;
971 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "p", &val))
972 return NULL__null;
973 bool old = use_tls_target_stack;
974 use_tls_target_stack = val;
975 // return the old value
976 if (old) {
977 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
978 } else {
979 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
980 }
981}
982
983static PyMethodDef ext_methods[] = {
984#define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS0x0001 , NULL__null }
985 declmethod(typeof_init),
986 declmethod(compute_fingerprint),
987 declmethod(set_use_tls_target_stack),
988 { NULL__null },
989#undef declmethod
990};
991
992
993MOD_INIT(_dispatcher)extern "C" PyObject* PyInit__dispatcher(void) {
994 if (import_devicearray() < 0) {
1
Taking false branch
995 PyErr_Print();
996 PyErr_SetString(PyExc_ImportError, "numba._devicearray failed to import");
997 return MOD_ERROR_VAL__null;
998 }
999
1000 PyObject *m;
1001 MOD_DEF(m, "_dispatcher", "No docs", ext_methods){ static struct PyModuleDef moduledef = { { { 1, __null }, __null
, 0, __null, }, "_dispatcher", "No docs", -1, ext_methods, __null
, __null, __null, __null }; m = PyModule_Create2(&moduledef
, 1013); }
2
Calling 'PyModule_Create2'
4
Returning from 'PyModule_Create2'
9
PyObject ownership leak with reference count of 1
1002 if (m == NULL__null)
5
Assuming 'm' is not equal to NULL
6
Taking false branch
1003 return MOD_ERROR_VAL__null;
1004
1005 DispatcherType.tp_new = PyType_GenericNew;
1006 if (PyType_Ready(&DispatcherType) < 0) {
7
Assuming the condition is true
8
Taking true branch
1007 return MOD_ERROR_VAL__null;
1008 }
1009 Py_INCREF(&DispatcherType)_Py_INCREF(((PyObject*)(&DispatcherType)));
1010 PyModule_AddObject(m, "Dispatcher", (PyObject*)(&DispatcherType));
1011
1012 return MOD_SUCCESS_VAL(m)m;
1013}

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

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