(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
deref-before-check-pr109060-haproxy-cfgparse.c
       1  /* Reduced from haproxy-2.7.1's cfgparse.c.  */
       2  
       3  typedef __SIZE_TYPE__ size_t;
       4  
       5  extern int
       6  strcmp(const char* __s1, const char* __s2)
       7    __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__))
       8    __attribute__((__nonnull__(1, 2)));
       9  
      10  extern int
      11  strncmp(const char* __s1, const char* __s2, size_t __n)
      12    __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__))
      13    __attribute__((__nonnull__(1, 2)));
      14  
      15  enum
      16  {
      17   /* [...snip...] */
      18    _ISdigit = ((3) < 8 ? ((1 << (3)) << 8) : ((1 << (3)) >> 8)),
      19   /* [...snip...] */
      20  };
      21  
      22  extern const unsigned short int**
      23  __ctype_b_loc(void) __attribute__((__nothrow__, __leaf__))
      24    __attribute__((__const__));
      25  
      26  unsigned int str2uic(const char* s);
      27  
      28  char*
      29  memprintf(char** out, const char* format, ...)
      30    __attribute__((format(printf, 2, 3)));
      31  
      32  int
      33  parse_process_number(const char* arg,
      34                       unsigned long* proc,
      35                       int max,
      36                       int* autoinc,
      37                       char** err)
      38  {
      39    if (autoinc) {
      40      *autoinc = 0;
      41      if (strncmp(arg, "auto:", 5) == 0) {
      42        arg += 5;
      43        *autoinc = 1;
      44      }
      45    }
      46  
      47    if (strcmp(arg, "all") == 0) /* { dg-bogus "pointer 'dash' is dereferenced here" } */
      48      *proc |= ~0UL;
      49    else if (strcmp(arg, "odd") == 0)
      50      *proc |= ~0UL / 3UL;
      51    else if (strcmp(arg, "even") == 0)
      52      *proc |= (~0UL / 3UL) << 1;
      53    else {
      54      const char *p, *dash = ((void*)0);
      55      unsigned int low, high;
      56  
      57      for (p = arg; *p; p++) {
      58        if (*p == '-' && !dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */
      59          dash = p;
      60        else if (!((*__ctype_b_loc())[(int)(((unsigned char)*p))] &
      61                   (unsigned short int)_ISdigit)) {
      62          memprintf(err, "'%s' is not a valid number/range.", arg);
      63          return -1;
      64        }
      65      }
      66  
      67      low = high = str2uic(arg);
      68      if (dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */
      69        high = ((!*(dash + 1)) ? max : str2uic(dash + 1));
      70  
      71      if (high < low) {
      72        unsigned int swap = low;
      73        low = high;
      74        high = swap;
      75      }
      76  
      77      if (low < 1 || low > max || high > max) {
      78        memprintf(err,
      79                  "'%s' is not a valid number/range."
      80                  " It supports numbers from 1 to %d.\n",
      81                  arg,
      82                  max);
      83        return 1;
      84      }
      85  
      86      for (; low <= high; low++)
      87        *proc |= 1UL << (low - 1);
      88    }
      89    *proc &= ~0UL >> (((unsigned int)sizeof(long) * 8) - max);
      90  
      91    return 0;
      92  }