1  /* Reduced from apr-1.7.0/tables/apr_hash.c: 'apr_hash_merge' */
       2  
       3  /* { dg-additional-options "-Wno-analyzer-too-complex" } */
       4  
       5  #define NULL ((void*)0)
       6  
       7  typedef __SIZE_TYPE__ size_t;
       8  
       9  extern void*
      10  memset(void* __s, int __c, size_t __n)
      11    __attribute__((__nothrow__, __leaf__, __nonnull__(1)));
      12  
      13  typedef struct apr_pool_t apr_pool_t;
      14  
      15  void*
      16  apr_palloc(apr_pool_t* p, size_t size)
      17    __attribute__((alloc_size(2), nonnull(1)));
      18  
      19  typedef struct apr_hash_t apr_hash_t;
      20  typedef struct apr_hash_index_t apr_hash_index_t;
      21  typedef unsigned int (*apr_hashfunc_t)(const char* key, size_t* klen);
      22  typedef struct apr_hash_entry_t apr_hash_entry_t;
      23  
      24  struct apr_hash_entry_t
      25  {
      26    apr_hash_entry_t* next;
      27    unsigned int hash;
      28    const void* key;
      29    size_t klen;
      30    const void* val;
      31  };
      32  
      33  struct apr_hash_t
      34  {
      35    apr_pool_t* pool;
      36    apr_hash_entry_t** array;
      37    /* [...snip.../ */
      38    unsigned int count, max, seed;
      39    apr_hashfunc_t hash_func;
      40    apr_hash_entry_t* free;
      41  };
      42  
      43  static apr_hash_entry_t**
      44  alloc_array(apr_hash_t* ht, unsigned int max)
      45  {
      46    return memset(apr_palloc(ht->pool, sizeof(*ht->array) * (max + 1)),
      47                  0,
      48                  sizeof(*ht->array) * (max + 1));
      49  }
      50  
      51  apr_hash_t*
      52  apr_hash_merge(apr_pool_t* p,
      53                 const apr_hash_t* overlay,
      54                 const apr_hash_t* base)
      55  {
      56    apr_hash_t* res;
      57    apr_hash_entry_t* new_vals = NULL;
      58    apr_hash_entry_t* iter;
      59    unsigned int i, j, k;
      60    res = apr_palloc(p, sizeof(apr_hash_t));
      61    res->pool = p;
      62    res->free = NULL;
      63    res->hash_func = base->hash_func;
      64    res->count = base->count;
      65    res->max = (overlay->max > base->max) ? overlay->max : base->max;
      66    if (base->count + overlay->count > res->max) {
      67      res->max = res->max * 2 + 1;
      68    }
      69    res->seed = base->seed;
      70    res->array = alloc_array(res, res->max);
      71    if (base->count + overlay->count) {
      72      new_vals =
      73        apr_palloc(p, sizeof(apr_hash_entry_t) * (base->count + overlay->count));
      74    }
      75    j = 0;
      76    for (k = 0; k <= base->max; k++) {
      77      for (iter = base->array[k]; iter; iter = iter->next) {
      78        i = iter->hash & res->max;
      79        /* We should only warn for the first of these
      80  	 (it's actually a false positive, but we don't have the
      81  	 invariante to know that).  */
      82        new_vals[j].klen = iter->klen;   /* { dg-warning "dereference of NULL 'new_vals'" } */
      83        /* ...but not for subsequent ones: */
      84        new_vals[j].key = iter->key;      /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */
      85        new_vals[j].val = iter->val;      /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */
      86        new_vals[j].hash = iter->hash;    /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */
      87        new_vals[j].next = res->array[i]; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */
      88        res->array[i] = &new_vals[j];     /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */
      89        j++;
      90      }
      91    }
      92    /* [...snip...] */
      93    return res;
      94  }