Merge patch series "Annotate switch/case fallthrough cases"

Andre Przywara <andre.przywara@arm.com> says:

C's implicit fallthrough behaviour in switch/case statements can lead to
subtle bugs. Quite some while ago many compilers introduced warnings in
those cases, requiring intentional fallthrough's to be annotated.

So far we were not enabling that compiler option, so many ambiguities
and some bugs in the code went unnoticed.

This series adds the required annotations in code paths that the first
stage of the U-Boot CI covers. There is a large number of cases left
in the libbz2 code. The usage of switch/case is borderline insane there,
labels are hidden in macros, and there are no breaks, but just goto's.
Upstream still uses very similar code, without any annotations. I still
am not 100% sure those are meant to fall through or not, and plan to do
further investigations, but didn't want to hold the rest of the patches
back. You can see for yourself by applying patch 18/18 and building for
sandbox64, for instance.

Because of this we cannot quite enable the warning in the Makefile yet,
but those fixes are worth regardless, and be it to increase readability.

Please note that those patches do not fix anything, really, they just add
those fallthrough annotations, so the series is not really critical.

Link: https://lore.kernel.org/r/20250327153313.2105227-1-andre.przywara@arm.com
This commit is contained in:
Tom Rini
2025-04-08 16:24:12 -06:00
19 changed files with 48 additions and 5 deletions

View File

@@ -266,6 +266,7 @@ u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
case BOOT_DEVICE_MMC: case BOOT_DEVICE_MMC:
if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK) if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK)
return MMCSD_MODE_RAW; return MMCSD_MODE_RAW;
fallthrough;
default: default:
return MMCSD_MODE_FS; return MMCSD_MODE_FS;
} }

View File

@@ -34,6 +34,7 @@ static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
printf("Can't get PMIC: %s!\n", name); printf("Can't get PMIC: %s!\n", name);
return failure(ret); return failure(ret);
} }
fallthrough;
case 1: case 1:
if (!currdev) { if (!currdev) {
printf("PMIC device is not set!\n\n"); printf("PMIC device is not set!\n\n");

View File

@@ -60,8 +60,10 @@ static int call_bootm(int argc, char *const argv[], const char *subcommand[])
switch (argc) { switch (argc) {
case 3: case 3:
bootm_argv[4] = argv[2]; /* fdt addr */ bootm_argv[4] = argv[2]; /* fdt addr */
fallthrough;
case 2: case 2:
bootm_argv[3] = argv[1]; /* initrd addr */ bootm_argv[3] = argv[1]; /* initrd addr */
fallthrough;
case 1: case 1:
bootm_argv[2] = argv[0]; /* kernel addr */ bootm_argv[2] = argv[0]; /* kernel addr */
} }

View File

@@ -484,7 +484,7 @@ int cmd_get_data_size(const char *arg, int default_size)
case 'q': case 'q':
if (MEM_SUPPORT_64BIT_DATA) if (MEM_SUPPORT_64BIT_DATA)
return 8; return 8;
/* no break */ fallthrough;
default: default:
return CMD_DATA_SIZE_ERR; return CMD_DATA_SIZE_ERR;
} }

View File

@@ -411,6 +411,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
return 0; return 0;
#endif #endif
/* If RAW mode fails, try FS mode. */ /* If RAW mode fails, try FS mode. */
fallthrough;
#ifdef CONFIG_SYS_MMCSD_FS_BOOT #ifdef CONFIG_SYS_MMCSD_FS_BOOT
case MMCSD_MODE_FS: case MMCSD_MODE_FS:
debug("spl: mmc boot mode: fs\n"); debug("spl: mmc boot mode: fs\n");

View File

@@ -186,6 +186,7 @@ void fastboot_multiresponse(int cmd, char *response)
} }
break; break;
} }
fallthrough;
default: default:
fastboot_fail("Unknown multiresponse command", response); fastboot_fail("Unknown multiresponse command", response);
break; break;

View File

@@ -795,6 +795,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
NAND_NCE | NAND_CTRL_CHANGE); NAND_NCE | NAND_CTRL_CHANGE);
/* This applies to read commands */ /* This applies to read commands */
fallthrough;
default: default:
/* /*
* If we don't have access to the busy pin, we apply the given * If we don't have access to the busy pin, we apply the given
@@ -4995,6 +4996,7 @@ int nand_scan_tail(struct mtd_info *mtd)
if (!ecc->read_page) if (!ecc->read_page)
ecc->read_page = nand_read_page_hwecc_oob_first; ecc->read_page = nand_read_page_hwecc_oob_first;
fallthrough;
case NAND_ECC_HW: case NAND_ECC_HW:
/* Use standard hwecc read page function? */ /* Use standard hwecc read page function? */
if (!ecc->read_page) if (!ecc->read_page)
@@ -5014,6 +5016,7 @@ int nand_scan_tail(struct mtd_info *mtd)
if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) if (!ecc->write_subpage && ecc->hwctl && ecc->calculate)
ecc->write_subpage = nand_write_subpage_hwecc; ecc->write_subpage = nand_write_subpage_hwecc;
fallthrough;
case NAND_ECC_HW_SYNDROME: case NAND_ECC_HW_SYNDROME:
if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) && if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) &&
(!ecc->read_page || (!ecc->read_page ||
@@ -5048,6 +5051,7 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->size, mtd->writesize); ecc->size, mtd->writesize);
ecc->mode = NAND_ECC_SOFT; ecc->mode = NAND_ECC_SOFT;
fallthrough;
case NAND_ECC_SOFT: case NAND_ECC_SOFT:
ecc->calculate = nand_calculate_ecc; ecc->calculate = nand_calculate_ecc;
ecc->correct = nand_correct_data; ecc->correct = nand_correct_data;

View File

@@ -219,6 +219,7 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
case SNOR_MFR_MICRON: case SNOR_MFR_MICRON:
/* Some Micron need WREN command; all will accept it */ /* Some Micron need WREN command; all will accept it */
need_wren = true; need_wren = true;
fallthrough;
case SNOR_MFR_MACRONIX: case SNOR_MFR_MACRONIX:
case SNOR_MFR_WINBOND: case SNOR_MFR_WINBOND:
if (need_wren) if (need_wren)

View File

@@ -934,6 +934,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
* be a result of power cut during erasure. * be a result of power cut during erasure.
*/ */
ai->maybe_bad_peb_count += 1; ai->maybe_bad_peb_count += 1;
fallthrough;
case UBI_IO_BAD_HDR: case UBI_IO_BAD_HDR:
if (ec_err) if (ec_err)
/* /*

View File

@@ -1400,12 +1400,15 @@ static int __init bytes_str_to_int(const char *str)
switch (*endp) { switch (*endp) {
case 'G': case 'G':
result *= 1024; result *= 1024;
fallthrough;
case 'M': case 'M':
result *= 1024; result *= 1024;
fallthrough;
case 'K': case 'K':
result *= 1024; result *= 1024;
if (endp[1] == 'i' && endp[2] == 'B') if (endp[1] == 'i' && endp[2] == 'B')
endp += 2; endp += 2;
fallthrough;
case '\0': case '\0':
break; break;
default: default:

View File

@@ -4830,6 +4830,7 @@ static int e1000_set_phy_type (struct e1000_hw *hw)
hw->phy_type = e1000_phy_igp; hw->phy_type = e1000_phy_igp;
break; break;
} }
fallthrough;
case IGP03E1000_E_PHY_ID: case IGP03E1000_E_PHY_ID:
hw->phy_type = e1000_phy_igp_3; hw->phy_type = e1000_phy_igp_3;
break; break;
@@ -4843,6 +4844,7 @@ static int e1000_set_phy_type (struct e1000_hw *hw)
hw->phy_type = e1000_phy_gg82563; hw->phy_type = e1000_phy_gg82563;
break; break;
} }
fallthrough;
case BME1000_E_PHY_ID: case BME1000_E_PHY_ID:
hw->phy_type = e1000_phy_bm; hw->phy_type = e1000_phy_bm;
break; break;

View File

@@ -335,6 +335,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
reg |= SC_RMII_EN | SC_ETCS_EXT_GMII; reg |= SC_RMII_EN | SC_ETCS_EXT_GMII;
break; break;
} }
fallthrough;
default: default:
debug("%s: Invalid PHY interface\n", __func__); debug("%s: Invalid PHY interface\n", __func__);
return -EINVAL; return -EINVAL;

View File

@@ -138,6 +138,7 @@ static int process_rqt_cmd(struct udevice *udc, const struct rqt_box *rqt)
case RQT_CMD_POWEROFF: case RQT_CMD_POWEROFF:
case RQT_CMD_EFSCLEAR: case RQT_CMD_EFSCLEAR:
send_rsp(udc, rsp); send_rsp(udc, rsp);
fallthrough;
default: default:
printf("Command not supported -> cmd: %d\n", rqt->rqt_data); printf("Command not supported -> cmd: %d\n", rqt->rqt_data);
return -EINVAL; return -EINVAL;

View File

@@ -1362,6 +1362,7 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,
databuf = root_hub_str_index1; databuf = root_hub_str_index1;
OK(len); OK(len);
} }
fallthrough;
default: default:
stat = USB_ST_STALLED; stat = USB_ST_STALLED;
} }

View File

@@ -352,7 +352,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
* since it uses the same rules as low speed interrupt * since it uses the same rules as low speed interrupt
* endpoints. * endpoints.
*/ */
fallthrough;
case USB_SPEED_LOW: case USB_SPEED_LOW:
if (usb_endpoint_xfer_int(endpt_desc) || if (usb_endpoint_xfer_int(endpt_desc) ||
usb_endpoint_xfer_isoc(endpt_desc)) { usb_endpoint_xfer_isoc(endpt_desc)) {

View File

@@ -245,6 +245,7 @@ int video_fill(struct udevice *dev, u32 colour)
*ppix++ = colour; *ppix++ = colour;
break; break;
} }
fallthrough;
case VIDEO_BPP32: case VIDEO_BPP32:
if (CONFIG_IS_ENABLED(VIDEO_BPP32)) { if (CONFIG_IS_ENABLED(VIDEO_BPP32)) {
u32 *ppix = priv->fb; u32 *ppix = priv->fb;
@@ -254,6 +255,7 @@ int video_fill(struct udevice *dev, u32 colour)
*ppix++ = colour; *ppix++ = colour;
break; break;
} }
fallthrough;
default: default:
memset(priv->fb, colour, priv->fb_size); memset(priv->fb, colour, priv->fb_size);
break; break;

View File

@@ -283,7 +283,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
break; break;
} }
islong = true; islong = true;
/* no break */ fallthrough;
case 'x': case 'x':
case 'X': case 'X':
if (islong) { if (islong) {

View File

@@ -420,6 +420,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
if (state->flags & 0x0200) CRC2(state->check, hold); if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = TIME; state->mode = TIME;
fallthrough;
case TIME: case TIME:
NEEDBITS(32); NEEDBITS(32);
if (state->head != Z_NULL) 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); if (state->flags & 0x0200) CRC4(state->check, hold);
INITBITS(); INITBITS();
state->mode = OS; state->mode = OS;
fallthrough;
case OS: case OS:
NEEDBITS(16); NEEDBITS(16);
if (state->head != Z_NULL) { 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); if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = EXLEN; state->mode = EXLEN;
fallthrough;
case EXLEN: case EXLEN:
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
NEEDBITS(16); NEEDBITS(16);
@@ -448,6 +451,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
else if (state->head != Z_NULL) else if (state->head != Z_NULL)
state->head->extra = Z_NULL; state->head->extra = Z_NULL;
state->mode = EXTRA; state->mode = EXTRA;
fallthrough;
case EXTRA: case EXTRA:
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
copy = state->length; copy = state->length;
@@ -471,6 +475,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
} }
state->length = 0; state->length = 0;
state->mode = NAME; state->mode = NAME;
fallthrough;
case NAME: case NAME:
if (state->flags & 0x0800) { if (state->flags & 0x0800) {
if (have == 0) goto inf_leave; 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->head->name = Z_NULL;
state->length = 0; state->length = 0;
state->mode = COMMENT; state->mode = COMMENT;
fallthrough;
case COMMENT: case COMMENT:
if (state->flags & 0x1000) { if (state->flags & 0x1000) {
if (have == 0) goto inf_leave; 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) else if (state->head != Z_NULL)
state->head->comment = Z_NULL; state->head->comment = Z_NULL;
state->mode = HCRC; state->mode = HCRC;
fallthrough;
case HCRC: case HCRC:
if (state->flags & 0x0200) { if (state->flags & 0x0200) {
NEEDBITS(16); NEEDBITS(16);
@@ -535,6 +542,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
strm->adler = state->check = REVERSE(hold); strm->adler = state->check = REVERSE(hold);
INITBITS(); INITBITS();
state->mode = DICT; state->mode = DICT;
fallthrough;
case DICT: case DICT:
if (state->havedict == 0) { if (state->havedict == 0) {
RESTORE(); RESTORE();
@@ -542,9 +550,11 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
} }
strm->adler = state->check = adler32(0L, Z_NULL, 0); strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE; state->mode = TYPE;
fallthrough;
case TYPE: case TYPE:
schedule(); schedule();
if (flush == Z_BLOCK) goto inf_leave; if (flush == Z_BLOCK) goto inf_leave;
fallthrough;
case TYPEDO: case TYPEDO:
if (state->last) { if (state->last) {
BYTEBITS(); BYTEBITS();
@@ -590,6 +600,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
state->length)); state->length));
INITBITS(); INITBITS();
state->mode = COPY; state->mode = COPY;
fallthrough;
case COPY: case COPY:
copy = state->length; copy = state->length;
if (copy) { if (copy) {
@@ -625,6 +636,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
Tracev((stderr, "inflate: table sizes ok\n")); Tracev((stderr, "inflate: table sizes ok\n"));
state->have = 0; state->have = 0;
state->mode = LENLENS; state->mode = LENLENS;
fallthrough;
case LENLENS: case LENLENS:
while (state->have < state->ncode) { while (state->have < state->ncode) {
NEEDBITS(3); NEEDBITS(3);
@@ -646,6 +658,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
Tracev((stderr, "inflate: code lengths ok\n")); Tracev((stderr, "inflate: code lengths ok\n"));
state->have = 0; state->have = 0;
state->mode = CODELENS; state->mode = CODELENS;
fallthrough;
case CODELENS: case CODELENS:
while (state->have < state->nlen + state->ndist) { while (state->have < state->nlen + state->ndist) {
for (;;) { for (;;) {
@@ -720,6 +733,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
} }
Tracev((stderr, "inflate: codes ok\n")); Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN; state->mode = LEN;
fallthrough;
case LEN: case LEN:
schedule(); schedule();
if (have >= 6 && left >= 258) { 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->extra = (unsigned)(this.op) & 15;
state->mode = LENEXT; state->mode = LENEXT;
fallthrough;
case LENEXT: case LENEXT:
if (state->extra) { if (state->extra) {
NEEDBITS(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)); Tracevv((stderr, "inflate: length %u\n", state->length));
state->mode = DIST; state->mode = DIST;
fallthrough;
case DIST: case DIST:
for (;;) { for (;;) {
this = state->distcode[BITS(state->distbits)]; 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->offset = (unsigned)this.val;
state->extra = (unsigned)(this.op) & 15; state->extra = (unsigned)(this.op) & 15;
state->mode = DISTEXT; state->mode = DISTEXT;
fallthrough;
case DISTEXT: case DISTEXT:
if (state->extra) { if (state->extra) {
NEEDBITS(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)); Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH; state->mode = MATCH;
fallthrough;
case MATCH: case MATCH:
if (left == 0) goto inf_leave; if (left == 0) goto inf_leave;
copy = out - left; copy = out - left;
@@ -872,6 +890,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
} }
#ifdef GUNZIP #ifdef GUNZIP
state->mode = LENGTH; state->mode = LENGTH;
fallthrough;
case LENGTH: case LENGTH:
if (state->wrap && state->flags) { if (state->wrap && state->flags) {
NEEDBITS(32); NEEDBITS(32);
@@ -885,6 +904,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
} }
#endif #endif
state->mode = DONE; state->mode = DONE;
fallthrough;
case DONE: case DONE:
ret = Z_STREAM_END; ret = Z_STREAM_END;
goto inf_leave; goto inf_leave;
@@ -894,6 +914,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush)
case MEM: case MEM:
return Z_MEM_ERROR; return Z_MEM_ERROR;
case SYNC: case SYNC:
fallthrough;
default: default:
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }

View File

@@ -1559,7 +1559,7 @@ common:
puts("*** ERROR: `ipaddr' not set\n"); puts("*** ERROR: `ipaddr' not set\n");
return 1; return 1;
} }
/* Fall through */ fallthrough;
#ifdef CONFIG_CMD_RARP #ifdef CONFIG_CMD_RARP
case RARP: case RARP: