| /* { dg-additional-options "-O3 -Wno-analyzer-too-complex" } */ |
| /* TODO: reduce this; was triggering this assert: |
| gcc_assert (pruned_state != existing_state); |
| */ |
| |
| typedef unsigned char Byte; |
| typedef unsigned int uInt; |
| |
| typedef void *voidp; |
| |
| typedef voidp (*alloc_func)(voidp opaque, uInt items, uInt size); |
| |
| typedef struct z_stream_s { |
| alloc_func zalloc; |
| voidp opaque; |
| } z_stream; |
| |
| typedef z_stream *z_streamp; |
| |
| typedef struct inflate_huft_s inflate_huft; |
| |
| struct inflate_huft_s { |
| struct { |
| Byte Exop; |
| Byte Bits; |
| } what; |
| uInt base; |
| }; |
| |
| static int huft_build(uInt *, uInt, uInt, const uInt *, const uInt *, |
| inflate_huft **, uInt *, inflate_huft *, uInt *, uInt *); |
| |
| static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, |
| inflate_huft **t, uInt *m, inflate_huft *hp, uInt *hn, |
| uInt *v) { |
| |
| uInt a; |
| uInt c[15 + 1]; |
| uInt f; |
| int g; |
| int h; |
| register uInt i; |
| register uInt j; |
| register int k; |
| int l; |
| uInt mask; |
| register uInt *p; |
| inflate_huft *q; |
| struct inflate_huft_s r; |
| inflate_huft *u[15]; |
| register int w; |
| uInt x[15 + 1]; |
| uInt *xp; |
| int y; |
| uInt z; |
| |
| p = c; |
| |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| *p++ = 0; |
| p = b; |
| i = n; |
| do { |
| c[*p++]++; |
| } while (--i); |
| if (c[0] == n) { |
| *t = (inflate_huft *)0; |
| *m = 0; |
| return 0; |
| } |
| |
| l = *m; |
| for (j = 1; j <= 15; j++) |
| if (c[j]) |
| break; |
| k = j; |
| if ((uInt)l < j) |
| l = j; |
| for (i = 15; i; i--) |
| if (c[i]) |
| break; |
| g = i; |
| if ((uInt)l > i) |
| l = i; |
| *m = l; |
| |
| for (y = 1 << j; j < i; j++, y <<= 1) |
| if ((y -= c[j]) < 0) |
| return (-3); |
| if ((y -= c[i]) < 0) |
| return (-3); |
| c[i] += y; |
| |
| x[1] = j = 0; |
| p = c + 1; |
| xp = x + 2; |
| while (--i) { |
| *xp++ = (j += *p++); |
| } |
| |
| p = b; |
| i = 0; |
| do { |
| if ((j = *p++) != 0) |
| v[x[j]++] = i; |
| } while (++i < n); |
| n = x[g]; |
| |
| x[0] = i = 0; |
| p = v; |
| h = -1; |
| w = -l; |
| u[0] = (inflate_huft *)0; |
| q = (inflate_huft *)0; |
| z = 0; |
| |
| for (; k <= g; k++) { |
| a = c[k]; |
| while (a--) { |
| |
| while (k > w + l) { |
| h++; |
| w += l; |
| |
| z = g - w; |
| z = z > (uInt)l ? l : z; |
| if ((f = 1 << (j = k - w)) > a + 1) { |
| f -= a + 1; |
| xp = c + k; |
| if (j < z) |
| while (++j < z) { |
| if ((f <<= 1) <= *++xp) |
| break; |
| f -= *xp; |
| } |
| } |
| z = 1 << j; |
| |
| if (*hn + z > 1440) |
| return (-4); |
| u[h] = q = hp + *hn; |
| *hn += z; |
| |
| if (h) { |
| x[h] = i; |
| r.what.Bits = (Byte)l; |
| r.what.Exop = (Byte)j; |
| j = i >> (w - l); |
| r.base = (uInt)(q - u[h - 1] - j); |
| u[h - 1][j] = r; |
| } else |
| *t = q; |
| } |
| |
| r.what.Bits = (Byte)(k - w); |
| if (p >= v + n) |
| r.what.Exop = 128 + 64; |
| else if (*p < s) { |
| r.what.Exop = (Byte)(*p < 256 ? 0 : 32 + 64); |
| r.base = *p++; |
| } else { |
| r.what.Exop = (Byte)(e[*p - s] + 16 + 64); |
| r.base = d[*p++ - s]; |
| } |
| |
| f = 1 << (k - w); |
| for (j = i >> w; j < z; j += f) |
| q[j] = r; /* { dg-warning "use of uninitialized value 'r.base'" } */ |
| |
| mask = (1 << w) - 1; |
| while ((i & mask) != x[h]) { |
| h--; |
| w -= l; |
| mask = (1 << w) - 1; |
| } |
| } |
| } |
| |
| return y != 0 && g != 1 ? (-5) : 0; |
| } |
| |
| extern const uInt cplens[31]; |
| extern const uInt cplext[31]; |
| extern const uInt cpdist[30]; |
| extern const uInt cpdext[30]; |
| |
| int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, |
| inflate_huft **tl, inflate_huft **td, |
| inflate_huft *hp, z_streamp z) { |
| int r; |
| uInt hn = 0; |
| uInt *v; |
| |
| if ((v = (uInt *)(*((z)->zalloc))((z)->opaque, (288), (sizeof(uInt)))) == 0) |
| return (-4); |
| |
| r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); |
| r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); |
| return 0; |
| } |