diff options
author | Tom Rini <trini@konsulko.com> | 2025-04-08 16:24:12 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-04-08 16:24:12 -0600 |
commit | 1f0281294d8bb1857076d27fd491c70c9808e474 (patch) | |
tree | 219ee816e561f4faf68adb7f4497f43bf6a0f1f4 | |
parent | fba8bfdd0bf2db1edd0383ba89a0c6037a6fe807 (diff) | |
parent | 9ce2986e7e57277bac3c528412c0bb4443b7003a (diff) |
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
-rw-r--r-- | arch/arm/mach-k3/am62px/am62p5_init.c | 1 | ||||
-rw-r--r-- | cmd/pmic.c | 1 | ||||
-rw-r--r-- | cmd/spl.c | 2 | ||||
-rw-r--r-- | common/command.c | 2 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 1 | ||||
-rw-r--r-- | drivers/fastboot/fb_command.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_base.c | 4 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-tiny.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/attach.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 3 | ||||
-rw-r--r-- | drivers/net/e1000.c | 2 | ||||
-rw-r--r-- | drivers/net/sun8i_emac.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/f_thor.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 2 | ||||
-rw-r--r-- | drivers/video/video-uclass.c | 2 | ||||
-rw-r--r-- | lib/tiny-printf.c | 2 | ||||
-rw-r--r-- | lib/zlib/inflate.c | 21 | ||||
-rw-r--r-- | net/net.c | 2 |
19 files changed, 48 insertions, 5 deletions
diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c b/arch/arm/mach-k3/am62px/am62p5_init.c index 14a46fa28d2..01e47deca94 100644 --- a/arch/arm/mach-k3/am62px/am62p5_init.c +++ b/arch/arm/mach-k3/am62px/am62p5_init.c @@ -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; } diff --git a/cmd/pmic.c b/cmd/pmic.c index 3ad1b8aa375..e5fc8f97b75 100644 --- a/cmd/pmic.c +++ b/cmd/pmic.c @@ -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"); diff --git a/cmd/spl.c b/cmd/spl.c index 76fe33762df..379b512f1ff 100644 --- a/cmd/spl.c +++ b/cmd/spl.c @@ -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 */ } diff --git a/common/command.c b/common/command.c index 3f691399cbe..0f9dd06d72b 100644 --- a/common/command.c +++ b/common/command.c @@ -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; } diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index fe4230170a0..d06f9f0dee6 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -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"); diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index e4484d65aca..2cdbac50ac4 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -186,6 +186,7 @@ void fastboot_multiresponse(int cmd, char *response) } break; } + fallthrough; default: fastboot_fail("Unknown multiresponse command", response); break; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index bb5460e0068..d3d1b93947b 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -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; diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c index 5755c5eed29..23de64a1520 100644 --- a/drivers/mtd/spi/spi-nor-tiny.c +++ b/drivers/mtd/spi/spi-nor-tiny.c @@ -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) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 2ef8fde3d32..306da509ec4 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -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) /* diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 104537784ab..50e43928af0 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -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: diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 8f432b8637b..b77298070f8 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -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; diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 0da182d9f4c..8433e7db265 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -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; diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c index 54372118348..540b9f88237 100644 --- a/drivers/usb/gadget/f_thor.c +++ b/drivers/usb/gadget/f_thor.c @@ -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; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index c020d13c43d..234a6f3645d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -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; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d30725d3fca..3ee1f67190f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -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)) { diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index ff4f2199585..c684c994b61 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -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; diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c index da2063d27c9..2a7a4d286c0 100644 --- a/lib/tiny-printf.c +++ b/lib/tiny-printf.c @@ -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) { 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; } diff --git a/net/net.c b/net/net.c index 1828f1cca36..5219367e391 100644 --- a/net/net.c +++ b/net/net.c @@ -1559,7 +1559,7 @@ common: puts("*** ERROR: `ipaddr' not set\n"); return 1; } - /* Fall through */ + fallthrough; #ifdef CONFIG_CMD_RARP case RARP: |