src/http/modules/ngx_http_limit_req_module.c:469: error: Integer Overflow L2
  ([0, +oo] - [0, 15]):unsigned64 by call to `ngx_slab_free_locked`.

src/http/modules/ngx_http_limit_req_module.c:469:9: Call
467.         ngx_rbtree_delete(&ctx->sh->rbtree, node);
468. 
469.         ngx_slab_free_locked(ctx->shpool, node);
             ^
470.     }
471. }

src/core/ngx_slab.c:412:1: Parameter `pool->pages->slab`
  410. 
  411. 
  412. void
       ^
  413. ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
  414. {

src/http/modules/ngx_http_limit_req_module.c:469:9: Call
467.         ngx_rbtree_delete(&ctx->sh->rbtree, node);
468. 
469.         ngx_slab_free_locked(ctx->shpool, node);
             ^
470.     }
471. }

src/core/ngx_slab.c:412:1: <LHS trace>
410. 
411. 
412. void
     ^
413. ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
414. {

src/core/ngx_slab.c:412:1: Global `ngx_pagesize_shift`
  410. 
  411. 
  412. void
       ^
  413. ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
  414. {

src/core/ngx_slab.c:412:1: <RHS trace>
410. 
411. 
412. void
     ^
413. ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
414. {

src/core/ngx_slab.c:412:1: Parameter `pool->pages->slab`
  410. 
  411. 
  412. void
       ^
  413. ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
  414. {

src/core/ngx_slab.c:429:5: Assignment
  427.     n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
  428.     page = &pool->pages[n];
  429.     slab = page->slab;
           ^
  430.     type = page->prev & NGX_SLAB_PAGE_MASK;
  431. 

src/core/ngx_slab.c:436:9: Assignment
  434.     case NGX_SLAB_SMALL:
  435. 
  436.         shift = slab & NGX_SLAB_SHIFT_MASK;
               ^
  437.         size = 1 << shift;
  438. 

src/core/ngx_slab.c:464:13: Binary operation: ([0, +oo] - [0, 15]):unsigned64 by call to `ngx_slab_free_locked` 
  462.             bitmap[n] &= ~m;
  463. 
  464.             n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);
                   ^
  465. 
  466.             if (n == 0) {

void
ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
{
    size_t            size;
    uintptr_t         slab, m, *bitmap;
    ngx_uint_t        n, type, slot, shift, map;
    ngx_slab_page_t  *slots, *page;
    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
    if ((u_char *) p < pool->start || (u_char *) p > pool->end) {
        ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_free(): outside of pool");
        goto fail;
    }
    n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
    page = &pool->pages[n];
    slab = page->slab;
    type = page->prev & NGX_SLAB_PAGE_MASK;
    switch (type) {
    case NGX_SLAB_SMALL:
        shift = slab & NGX_SLAB_SHIFT_MASK;
        size = 1 << shift;
        if ((uintptr_t) p & (size - 1)) {
            goto wrong_chunk;
        }
        n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
        m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));
        n /= (sizeof(uintptr_t) * 8);
        bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));
        if (bitmap[n] & m) {
            if (page->next == NULL) {
                slots = (ngx_slab_page_t *)
                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));
                slot = shift - pool->min_shift;
                page->next = slots[slot].next;
                slots[slot].next = page;
                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
                page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;
            }
            bitmap[n] &= ~m;
            n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);
            if (n == 0) {
                n = 1;
            }
            if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
                goto done;
            }
            map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
            for (n = 1; n < map; n++) {
                if (bitmap[n]) {
                    goto done;
                }
            }
            ngx_slab_free_pages(pool, page, 1);
            goto done;
        }
        goto chunk_already_free;
    case NGX_SLAB_EXACT:
        m = (uintptr_t) 1 <<
                (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
        size = ngx_slab_exact_size;
        if ((uintptr_t) p & (size - 1)) {
            goto wrong_chunk;
        }
        if (slab & m) {
            if (slab == NGX_SLAB_BUSY) {
                slots = (ngx_slab_page_t *)
                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));
                slot = ngx_slab_exact_shift - pool->min_shift;
                page->next = slots[slot].next;
                slots[slot].next = page;
                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
                page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;
            }
            page->slab &= ~m;
            if (page->slab) {
                goto done;
            }
            ngx_slab_free_pages(pool, page, 1);
            goto done;
        }
        goto chunk_already_free;
    case NGX_SLAB_BIG:
        shift = slab & NGX_SLAB_SHIFT_MASK;
        size = 1 << shift;
        if ((uintptr_t) p & (size - 1)) {
            goto wrong_chunk;
        }
        m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
                              + NGX_SLAB_MAP_SHIFT);
        if (slab & m) {
            if (page->next == NULL) {
                slots = (ngx_slab_page_t *)
                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));
                slot = shift - pool->min_shift;
                page->next = slots[slot].next;
                slots[slot].next = page;
                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
                page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;
            }
            page->slab &= ~m;
            if (page->slab & NGX_SLAB_MAP_MASK) {
                goto done;
            }
            ngx_slab_free_pages(pool, page, 1);
            goto done;
        }
        goto chunk_already_free;
    case NGX_SLAB_PAGE:
        if ((uintptr_t) p & (ngx_pagesize - 1)) {
            goto wrong_chunk;
        }
        if (slab == NGX_SLAB_PAGE_FREE) {
            ngx_slab_error(pool, NGX_LOG_ALERT,
                           "ngx_slab_free(): page is already free");
            goto fail;
        }
        if (slab == NGX_SLAB_PAGE_BUSY) {
            ngx_slab_error(pool, NGX_LOG_ALERT,
                           "ngx_slab_free(): pointer to wrong page");
            goto fail;
        }
        n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
        size = slab & ~NGX_SLAB_PAGE_START;
        ngx_slab_free_pages(pool, &pool->pages[n], size);
        ngx_slab_junk(p, size << ngx_pagesize_shift);
        return;
    }
    return;
done:
    ngx_slab_junk(p, size);
    return;
wrong_chunk:
    ngx_slab_error(pool, NGX_LOG_ALERT,
                   "ngx_slab_free(): pointer to wrong chunk");
    goto fail;
chunk_already_free:
    ngx_slab_error(pool, NGX_LOG_ALERT,
                   "ngx_slab_free(): chunk is already free");
fail:
    return;
}
['static void\nngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)\n{\n    ngx_int_t                   excess;\n    ngx_time_t                 *tp;\n    ngx_msec_t                  now;\n    ngx_queue_t                *q;\n    ngx_msec_int_t              ms;\n    ngx_rbtree_node_t          *node;\n    ngx_http_limit_req_node_t  *lr;\n    tp = ngx_timeofday();\n    now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);\n    while (n < 3) {\n        if (ngx_queue_empty(&ctx->sh->queue)) {\n            return;\n        }\n        q = ngx_queue_last(&ctx->sh->queue);\n        lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue);\n        if (n++ != 0) {\n            ms = (ngx_msec_int_t) (now - lr->last);\n            ms = ngx_abs(ms);\n            if (ms < 60000) {\n                return;\n            }\n            excess = lr->excess - ctx->rate * ms / 1000;\n            if (excess > 0) {\n                return;\n            }\n        }\n        ngx_queue_remove(q);\n        node = (ngx_rbtree_node_t *)\n                   ((u_char *) lr - offsetof(ngx_rbtree_node_t, color));\n        ngx_rbtree_delete(&ctx->sh->rbtree, node);\n        ngx_slab_free_locked(ctx->shpool, node);\n    }\n}', 'void\nngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)\n{\n    size_t            size;\n    uintptr_t         slab, m, *bitmap;\n    ngx_uint_t        n, type, slot, shift, map;\n    ngx_slab_page_t  *slots, *page;\n    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);\n    if ((u_char *) p < pool->start || (u_char *) p > pool->end) {\n        ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_free(): outside of pool");\n        goto fail;\n    }\n    n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;\n    page = &pool->pages[n];\n    slab = page->slab;\n    type = page->prev & NGX_SLAB_PAGE_MASK;\n    switch (type) {\n    case NGX_SLAB_SMALL:\n        shift = slab & NGX_SLAB_SHIFT_MASK;\n        size = 1 << shift;\n        if ((uintptr_t) p & (size - 1)) {\n            goto wrong_chunk;\n        }\n        n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;\n        m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));\n        n /= (sizeof(uintptr_t) * 8);\n        bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));\n        if (bitmap[n] & m) {\n            if (page->next == NULL) {\n                slots = (ngx_slab_page_t *)\n                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));\n                slot = shift - pool->min_shift;\n                page->next = slots[slot].next;\n                slots[slot].next = page;\n                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;\n                page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;\n            }\n            bitmap[n] &= ~m;\n            n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);\n            if (n == 0) {\n                n = 1;\n            }\n            if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {\n                goto done;\n            }\n            map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);\n            for (n = 1; n < map; n++) {\n                if (bitmap[n]) {\n                    goto done;\n                }\n            }\n            ngx_slab_free_pages(pool, page, 1);\n            goto done;\n        }\n        goto chunk_already_free;\n    case NGX_SLAB_EXACT:\n        m = (uintptr_t) 1 <<\n                (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);\n        size = ngx_slab_exact_size;\n        if ((uintptr_t) p & (size - 1)) {\n            goto wrong_chunk;\n        }\n        if (slab & m) {\n            if (slab == NGX_SLAB_BUSY) {\n                slots = (ngx_slab_page_t *)\n                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));\n                slot = ngx_slab_exact_shift - pool->min_shift;\n                page->next = slots[slot].next;\n                slots[slot].next = page;\n                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;\n                page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;\n            }\n            page->slab &= ~m;\n            if (page->slab) {\n                goto done;\n            }\n            ngx_slab_free_pages(pool, page, 1);\n            goto done;\n        }\n        goto chunk_already_free;\n    case NGX_SLAB_BIG:\n        shift = slab & NGX_SLAB_SHIFT_MASK;\n        size = 1 << shift;\n        if ((uintptr_t) p & (size - 1)) {\n            goto wrong_chunk;\n        }\n        m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)\n                              + NGX_SLAB_MAP_SHIFT);\n        if (slab & m) {\n            if (page->next == NULL) {\n                slots = (ngx_slab_page_t *)\n                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));\n                slot = shift - pool->min_shift;\n                page->next = slots[slot].next;\n                slots[slot].next = page;\n                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;\n                page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;\n            }\n            page->slab &= ~m;\n            if (page->slab & NGX_SLAB_MAP_MASK) {\n                goto done;\n            }\n            ngx_slab_free_pages(pool, page, 1);\n            goto done;\n        }\n        goto chunk_already_free;\n    case NGX_SLAB_PAGE:\n        if ((uintptr_t) p & (ngx_pagesize - 1)) {\n            goto wrong_chunk;\n        }\n        if (slab == NGX_SLAB_PAGE_FREE) {\n            ngx_slab_error(pool, NGX_LOG_ALERT,\n                           "ngx_slab_free(): page is already free");\n            goto fail;\n        }\n        if (slab == NGX_SLAB_PAGE_BUSY) {\n            ngx_slab_error(pool, NGX_LOG_ALERT,\n                           "ngx_slab_free(): pointer to wrong page");\n            goto fail;\n        }\n        n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;\n        size = slab & ~NGX_SLAB_PAGE_START;\n        ngx_slab_free_pages(pool, &pool->pages[n], size);\n        ngx_slab_junk(p, size << ngx_pagesize_shift);\n        return;\n    }\n    return;\ndone:\n    ngx_slab_junk(p, size);\n    return;\nwrong_chunk:\n    ngx_slab_error(pool, NGX_LOG_ALERT,\n                   "ngx_slab_free(): pointer to wrong chunk");\n    goto fail;\nchunk_already_free:\n    ngx_slab_error(pool, NGX_LOG_ALERT,\n                   "ngx_slab_free(): chunk is already free");\nfail:\n    return;\n}']