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:
if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK)
return MMCSD_MODE_RAW;
fallthrough;
default:
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);
return failure(ret);
}
fallthrough;
case 1:
if (!currdev) {
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) {
case 3:
bootm_argv[4] = argv[2]; /* fdt addr */
fallthrough;
case 2:
bootm_argv[3] = argv[1]; /* initrd addr */
fallthrough;
case 1:
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':
if (MEM_SUPPORT_64BIT_DATA)
return 8;
/* no break */
fallthrough;
default:
return CMD_DATA_SIZE_ERR;
}

View File

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

View File

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

View File

@@ -795,6 +795,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
NAND_NCE | NAND_CTRL_CHANGE);
/* This applies to read commands */
fallthrough;
default:
/*
* 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)
ecc->read_page = nand_read_page_hwecc_oob_first;
fallthrough;
case NAND_ECC_HW:
/* Use standard hwecc read page function? */
if (!ecc->read_page)
@@ -5014,6 +5016,7 @@ int nand_scan_tail(struct mtd_info *mtd)
if (!ecc->write_subpage && ecc->hwctl && ecc->calculate)
ecc->write_subpage = nand_write_subpage_hwecc;
fallthrough;
case NAND_ECC_HW_SYNDROME:
if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) &&
(!ecc->read_page ||
@@ -5048,6 +5051,7 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->size, mtd->writesize);
ecc->mode = NAND_ECC_SOFT;
fallthrough;
case NAND_ECC_SOFT:
ecc->calculate = nand_calculate_ecc;
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:
/* Some Micron need WREN command; all will accept it */
need_wren = true;
fallthrough;
case SNOR_MFR_MACRONIX:
case SNOR_MFR_WINBOND:
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.
*/
ai->maybe_bad_peb_count += 1;
fallthrough;
case UBI_IO_BAD_HDR:
if (ec_err)
/*

View File

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

View File

@@ -4830,6 +4830,7 @@ static int e1000_set_phy_type (struct e1000_hw *hw)
hw->phy_type = e1000_phy_igp;
break;
}
fallthrough;
case IGP03E1000_E_PHY_ID:
hw->phy_type = e1000_phy_igp_3;
break;
@@ -4843,6 +4844,7 @@ static int e1000_set_phy_type (struct e1000_hw *hw)
hw->phy_type = e1000_phy_gg82563;
break;
}
fallthrough;
case BME1000_E_PHY_ID:
hw->phy_type = e1000_phy_bm;
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;
break;
}
fallthrough;
default:
debug("%s: Invalid PHY interface\n", __func__);
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_EFSCLEAR:
send_rsp(udc, rsp);
fallthrough;
default:
printf("Command not supported -> cmd: %d\n", rqt->rqt_data);
return -EINVAL;

View File

@@ -1361,7 +1361,8 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,
wLength));
databuf = root_hub_str_index1;
OK(len);
}
}
fallthrough;
default:
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
* endpoints.
*/
fallthrough;
case USB_SPEED_LOW:
if (usb_endpoint_xfer_int(endpt_desc) ||
usb_endpoint_xfer_isoc(endpt_desc)) {

View File

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

View File

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

View File

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