aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/c-c++-common/analyzer/pr104029.c
blob: 04b9ef872a3aaa23a20c710471449455d3352c80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
typedef __SIZE_TYPE__ size_t;
typedef const void *t_comptype;
typedef int (*t_compfunc)(t_comptype, t_comptype);

extern int *__errno_location(void)
  __attribute__((__nothrow__, __leaf__,__const__));
extern void free(void *__ptr)
  __attribute__((__nothrow__, __leaf__));
extern void *my_malloc1(const char *file, int line, size_t size);

int heapsort(void *vbase, size_t nmemb, size_t size, t_compfunc compar) {
  char tmp, *tmp1, *tmp2, *abase, *k, *p, *t;
  size_t cnt, i, j, l;

  if (nmemb <= 1)
    return (0);

  if (!size) {
    (*__errno_location()) = 22;
    return (-1);
  }

  k = (char *) my_malloc1(__FILE__, __LINE__, size);

  abase = (char *)vbase - size;

  for (l = nmemb / 2 + 1; --l;) {
    for (i = l; (j = i * 2) <= nmemb; i = j) {
      p = abase + j * size;
      if (j < nmemb && compar(p, p + size) < 0) {
        p += size;
        ++j;
      }
      t = abase + i * size;
      if (compar(p, t) <= 0)
        break;
      {
        cnt = size;
        do {
          tmp = *t;
          *t++ = *p;
          *p++ = tmp;
        } while (--cnt);
      };
    }
  };

  while (nmemb > 1) {
    {
      cnt = size;
      tmp1 = k;
      tmp2 = abase + nmemb * size;
      do {
        *tmp1++ = *tmp2++;
      } while (--cnt);
    };
    {
      cnt = size;
      tmp1 = abase + nmemb * size;
      tmp2 = abase + size;
      do {
        *tmp1++ = *tmp2++;
      } while (--cnt);
    };
    --nmemb;
    {
      for (i = 1; (j = i * 2) <= nmemb; i = j) {
        p = abase + j * size;
        if (j < nmemb && compar(p, p + size) < 0) {
          p += size;
          ++j;
        }
        t = abase + i * size;
        {
          cnt = size;
          tmp1 = t;
          tmp2 = p;
          do {
            *tmp1++ = *tmp2++;
          } while (--cnt);
        };
      }
      for (;;) {
        j = i;
        i = j / 2;
        p = abase + j * size;
        t = abase + i * size;
        if (j == 1 || compar(k, t) < 0) {
          {
            cnt = size;
            tmp1 = p;
            tmp2 = k;
            do {
              *tmp1++ = *tmp2++;
            } while (--cnt);
          };
          break;
        }
        {
          cnt = size;
          tmp1 = p;
          tmp2 = t;
          do {
            *tmp1++ = *tmp2++;
          } while (--cnt);
        };
      }
    };
  }
  free(k);
  return (0);
}