The inflate state machine in zlib uses switch/case fall-through's extensively, as it sometimes advances the state, and lets the conveniently placed next case statement handle the new state already. The pattern here is: state->mode = LEN; case LEN:
Annotate those occasions with the "fallthrough;" macro, to let compilers know this is fine when using -Wimplicit-fallthrough. This mimics the upstream commit 76f70abbc73f: Author: Mark Adler <mad...@alumni.caltech.edu> Date: Sun Mar 27 00:12:38 2022 -0700 Subject: Add fallthrough comments for gcc. Signed-off-by: Andre Przywara <andre.przyw...@arm.com> --- lib/zlib/inflate.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c index b4c72cc2c5c..2b7a464f74f 100644 --- a/lib/zlib/inflate.c +++ b/lib/zlib/inflate.c @@ -420,6 +420,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; + fallthrough; case TIME: NEEDBITS(32); if (state->head != Z_NULL) @@ -427,6 +428,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; + fallthrough; case OS: NEEDBITS(16); if (state->head != Z_NULL) { @@ -436,6 +438,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; + fallthrough; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); @@ -448,6 +451,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; + fallthrough; case EXTRA: if (state->flags & 0x0400) { copy = state->length; @@ -471,6 +475,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } state->length = 0; state->mode = NAME; + fallthrough; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; @@ -492,6 +497,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; + fallthrough; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; @@ -512,6 +518,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; + fallthrough; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); @@ -535,6 +542,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; + fallthrough; case DICT: if (state->havedict == 0) { RESTORE(); @@ -542,9 +550,11 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; + fallthrough; case TYPE: schedule(); if (flush == Z_BLOCK) goto inf_leave; + fallthrough; case TYPEDO: if (state->last) { BYTEBITS(); @@ -590,6 +600,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->length)); INITBITS(); state->mode = COPY; + fallthrough; case COPY: copy = state->length; if (copy) { @@ -625,6 +636,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; + fallthrough; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); @@ -646,6 +658,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; + fallthrough; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { @@ -720,6 +733,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; + fallthrough; case LEN: schedule(); if (have >= 6 && left >= 258) { @@ -764,6 +778,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; + fallthrough; case LENEXT: if (state->extra) { NEEDBITS(state->extra); @@ -772,6 +787,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracevv((stderr, "inflate: length %u\n", state->length)); state->mode = DIST; + fallthrough; case DIST: for (;;) { this = state->distcode[BITS(state->distbits)]; @@ -797,6 +813,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->offset = (unsigned)this.val; state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; + fallthrough; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); @@ -817,6 +834,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; + fallthrough; case MATCH: if (left == 0) goto inf_leave; copy = out - left; @@ -872,6 +890,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } #ifdef GUNZIP state->mode = LENGTH; + fallthrough; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); @@ -885,6 +904,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } #endif state->mode = DONE; + fallthrough; case DONE: ret = Z_STREAM_END; goto inf_leave; @@ -894,6 +914,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) case MEM: return Z_MEM_ERROR; case SYNC: + fallthrough; default: return Z_STREAM_ERROR; } -- 2.25.1