File: src/BTrees/BucketTemplate.c
Function: _bucket_set
Error: ob_refcnt of '*keyarg' is 1 too low
290 static int
291 _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
292             int unique, int noval, int *changed)
293 {
when considering range: -128 <= value <= 1
taking False path
294     int i, cmp;
295     KEY_TYPE key;
296 
297     /* Subtle:  there may or may not be a value.  If there is, we need to
298      * check its type early, so that in case of error we can get out before
299      * mutating the bucket.  But because value isn't used on all paths, if
300      * we don't initialize value then gcc gives a nuisance complaint that
301      * value may be used initialized (it can't be, but gcc doesn't know
302      * that).  So we initialize it.  However, VALUE_TYPE can be various types,
303      * including int, PyObject*, and char[6], so it's a puzzle to spell
304      * initialization.  It so happens that {0} is a valid initializer for all
305      * these types.
306      */
307     VALUE_TYPE value = {0};	/* squash nuisance warning */
308     int result = -1;    /* until proven innocent */
309     int copied = 1;
310 
311     COPY_KEY_FROM_ARG(key, keyarg, copied);
312     UNLESS(copied) return -1;
taking False path
313 
314     /* Copy the value early (if needed), so that in case of error a
315      * pile of bucket mutations don't need to be undone.
316      */
317     if (v && !noval) {
when considering range: -0x80000000 <= value <= -1
taking False path
318     	COPY_VALUE_FROM_ARG(value, v, copied);
319     	UNLESS(copied) return -1;
320     }
321 
322     UNLESS (PER_USE(self)) return -1;
when considering range: -128 <= value <= -2
taking True path
when considering range: -128 <= value <= -1
taking False path
taking False path
323 
324     BUCKET_SEARCH(i, cmp, self, key, goto Done);
when considering range: -0x80000000 <= _hi <= 0
taking False path
325     if (cmp == 0) {
taking False path
326         /* The key exists, at index i. */
327 
328         if (v) {
329             /* The key exists at index i, and there's a new value.
330              * If unique, we're not supposed to replace it.  If noval, or this
331              * is a set bucket (self->values is NULL), there's nothing to do.
332              */
333             if (unique || noval || self->values == NULL) {
334                 result = 0;
335                 goto Done;
336             }
337 
338             /* The key exists at index i, and we need to replace the value. */
339 #ifdef VALUE_SAME
340             /* short-circuit if no change */
341             if (VALUE_SAME(self->values[i], value)) {
342                 result = 0;
343                 goto Done;
344             }
345 #endif
346             if (changed)
347                 *changed = 1;
348             DECREF_VALUE(self->values[i]);
349             COPY_VALUE(self->values[i], value);
350             INCREF_VALUE(self->values[i]);
351             if (PER_CHANGED(self) >= 0)
352                 result = 0;
353             goto Done;
354         }
355 
356         /* The key exists at index i, and should be deleted. */
357         DECREF_KEY(self->keys[i]);
358         self->len--;
359         if (i < self->len)
360             memmove(self->keys + i, self->keys + i+1,
361                     sizeof(KEY_TYPE)*(self->len - i));
362 
363         if (self->values) {
364             DECREF_VALUE(self->values[i]);
365             if (i < self->len)
366                 memmove(self->values + i, self->values + i+1,
367                         sizeof(VALUE_TYPE)*(self->len - i));
368         }
369 
370         if (! self->len) {
371             self->size = 0;
372             free(self->keys);
373             self->keys = NULL;
374             if (self->values) {
375                 free(self->values);
376                 self->values = NULL;
377             }
378         }
379 
380         if (changed)
381             *changed = 1;
382         if (PER_CHANGED(self) >= 0)
383             result = 1;
384         goto Done;
385     }
386 
387     /* The key doesn't exist, and belongs at index i. */
388     if (!v) {
taking False path
389         /* Can't delete a non-existent key. */
390         PyErr_SetObject(PyExc_KeyError, keyarg);
391         goto Done;
392     }
393 
394     /* The key doesn't exist and should be inserted at index i. */
395     if (self->len == self->size && Bucket_grow(self, -1, noval) < 0)
when taking True path
when considering range: 0 <= value <= 0x7fffffff
taking False path
396         goto Done;
397 
398     if (self->len > i) {
when taking True path
399         memmove(self->keys + i + 1, self->keys + i,
400                 sizeof(KEY_TYPE) * (self->len - i));
401         if (self->values) {
when treating unknown struct PyObject * * from src/BTrees/BucketTemplate.c:401 as non-NULL
taking True path
402             memmove(self->values + i + 1, self->values + i,
403                     sizeof(VALUE_TYPE) * (self->len - i));
404         }
405     }
406 
407     COPY_KEY(self->keys[i], key);
when treating unknown struct PyObject * * from src/BTrees/BucketTemplate.c:407 as non-NULL
'*keyarg' is now referenced by 1 non-stack value(s): heap-region-17
408     INCREF_KEY(self->keys[i]);
when treating unknown struct PyObject * * from src/BTrees/BucketTemplate.c:408 as non-NULL
when treating unknown struct PyObject * from src/BTrees/BucketTemplate.c:408 as non-NULL
409 
410     if (! noval) {
taking False path
411         COPY_VALUE(self->values[i], value);
412         INCREF_VALUE(self->values[i]);
413     }
414 
415     self->len++;
416     if (changed)
when taking False path
417         *changed = 1;
418     if (PER_CHANGED(self) >= 0)
when treating unknown struct cPersistenceCAPIstruct * from src/persistent/cPersistence.h:112 as non-NULL
calling unknown int (*) (struct cPersistentObject *) from src/BTrees/BucketTemplate.c:418
when considering range: 0 <= value <= 0x7fffffff
taking True path
419         result = 1;
420 
421 Done:
422     PER_UNUSE(self);
calling unknown void (*) (struct cPersistentObject *) from src/BTrees/BucketTemplate.c:422
423     return result;
424 }
ob_refcnt of '*keyarg' is 1 too low
was expecting final ob_refcnt to be N + 1 (for some unknown N)
due to object being referenced by: heap-region-17
but final ob_refcnt is N + 0
found 10 similar trace(s) to this