1  /* Reduced from coreutils's sum.c: bsd_sum_stream */
       2  
       3  typedef long unsigned int size_t;
       4  typedef unsigned char __uint8_t;
       5  typedef unsigned long int __uintmax_t;
       6  typedef struct _IO_FILE FILE;
       7  extern size_t
       8  fread_unlocked(void* __restrict __ptr,
       9                 size_t __size,
      10                 size_t __n,
      11                 FILE* __restrict __stream);
      12  extern int
      13  feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__));
      14  extern int
      15  ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__));
      16  extern void*
      17  memcpy(void* __restrict __dest, const void* __restrict __src, size_t __n)
      18    __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2)));
      19  extern void
      20  rpl_free(void*);
      21  extern int*
      22  __errno_location(void) __attribute__((__nothrow__, __leaf__))
      23  __attribute__((__const__));
      24  extern void*
      25  malloc(size_t __size) __attribute__((__nothrow__, __leaf__))
      26  __attribute__((__malloc__)) __attribute__((__alloc_size__(1)));
      27  typedef __uint8_t uint8_t;
      28  typedef __uintmax_t uintmax_t;
      29  
      30  int
      31  bsd_sum_stream(FILE* stream, void* resstream, uintmax_t* length)
      32  {
      33    int ret = -1;
      34    size_t sum, n;
      35    int checksum = 0;
      36    uintmax_t total_bytes = 0;
      37    static const size_t buffer_length = 32768;
      38    uint8_t* buffer = malloc(buffer_length);
      39  
      40    if (!buffer)
      41      return -1;
      42  
      43    while (1) {
      44      sum = 0;
      45  
      46      while (1) {
      47        n = fread_unlocked(buffer + sum, 1, buffer_length - sum, stream);
      48        sum += n;
      49  
      50        if (buffer_length == sum)
      51          break;
      52  
      53        if (n == 0) {
      54          if (ferror_unlocked(stream))
      55            goto cleanup_buffer;
      56          goto final_process;
      57        }
      58  
      59        if (feof_unlocked(stream))
      60          goto final_process;
      61      }
      62  
      63      for (size_t i = 0; i < sum; i++) {
      64        checksum = (checksum >> 1) + ((checksum & 1) << 15);
      65        checksum += buffer[i]; /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */
      66        checksum &= 0xffff;
      67      }
      68      if (total_bytes + sum < total_bytes) {
      69  
      70        (*__errno_location()) = 75;
      71        goto cleanup_buffer;
      72      }
      73      total_bytes += sum;
      74    }
      75  
      76  final_process:;
      77  
      78    for (size_t i = 0; i < sum; i++) {
      79      checksum = (checksum >> 1) + ((checksum & 1) << 15);
      80      checksum += buffer[i];  /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */
      81      checksum &= 0xffff;
      82    }
      83    if (total_bytes + sum < total_bytes) {
      84  
      85      (*__errno_location()) = 75;
      86      goto cleanup_buffer;
      87    }
      88    total_bytes += sum;
      89  
      90    memcpy(resstream, &checksum, sizeof checksum);
      91    *length = total_bytes;
      92    ret = 0;
      93  cleanup_buffer:
      94  
      95    rpl_free(buffer);
      96    return ret;
      97  }
      98