diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c index 5196c3e5cb..34aa8ba51a 100644 --- a/cmd/mount_zfs/mount_zfs.c +++ b/cmd/mount_zfs/mount_zfs.c @@ -367,7 +367,7 @@ main(int argc, char **argv) "mount the filesystem again.\n"), dataset); return (MOUNT_SYSERR); } - /* fallthru */ + fallthrough; #endif default: (void) fprintf(stderr, gettext("filesystem " diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index cd14ddfcf6..7322cc1432 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -4564,7 +4564,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name) case DMU_OT_DIRECTORY_CONTENTS: if (s != NULL && *(s + 1) != '\0') return (dump_path_impl(os, child_obj, s + 1)); - /*FALLTHROUGH*/ + fallthrough; case DMU_OT_PLAIN_FILE_CONTENTS: dump_object(os, child_obj, dump_opt['v'], &header, NULL, 0); return (0); diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index b18e68fef0..92aafb0916 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -7310,6 +7310,7 @@ unshare_unmount(int op, int argc, char **argv) if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) continue; + break; default: break; } diff --git a/config/Rules.am b/config/Rules.am index e9cd134ede..1a63109fc2 100644 --- a/config/Rules.am +++ b/config/Rules.am @@ -26,6 +26,7 @@ AM_LIBTOOLFLAGS = --silent AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes AM_CFLAGS += -fno-strict-aliasing AM_CFLAGS += $(NO_OMIT_FRAME_POINTER) +AM_CFLAGS += $(IMPLICIT_FALLTHROUGH) AM_CFLAGS += $(DEBUG_CFLAGS) AM_CFLAGS += $(ASAN_CFLAGS) AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH) diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 index a841233179..ce84f7e606 100644 --- a/config/always-compiler-options.m4 +++ b/config/always-compiler-options.m4 @@ -161,6 +161,29 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE], [ AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE]) ]) +dnl # +dnl # Check if gcc supports -Wimplicit-fallthrough option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH], [ + AC_MSG_CHECKING([whether $CC supports -Wimplicit-fallthrough]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + IMPLICIT_FALLTHROUGH=-Wimplicit-fallthrough + AC_DEFINE([HAVE_IMPLICIT_FALLTHROUGH], 1, + [Define if compiler supports -Wimplicit-fallthrough]) + AC_MSG_RESULT([yes]) + ], [ + IMPLICIT_FALLTHROUGH= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([IMPLICIT_FALLTHROUGH]) +]) + dnl # dnl # Check if gcc supports -fno-omit-frame-pointer option. dnl # diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index 305d0c6936..b36fc4dcaa 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -158,6 +158,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE + ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH diff --git a/include/os/freebsd/linux/compiler.h b/include/os/freebsd/linux/compiler.h index 05e93efa64..20903717b5 100644 --- a/include/os/freebsd/linux/compiler.h +++ b/include/os/freebsd/linux/compiler.h @@ -67,6 +67,7 @@ #define __always_inline inline #define noinline __noinline #define ____cacheline_aligned __aligned(CACHE_LINE_SIZE) +#define fallthrough __attribute__((__fallthrough__)) #if !defined(_KERNEL) && !defined(_STANDALONE) #define likely(x) __builtin_expect(!!(x), 1) diff --git a/include/os/linux/kernel/linux/compiler_compat.h b/include/os/linux/kernel/linux/compiler_compat.h index 921d32f246..2c0704da2e 100644 --- a/include/os/linux/kernel/linux/compiler_compat.h +++ b/include/os/linux/kernel/linux/compiler_compat.h @@ -28,6 +28,14 @@ #include +#if !defined(fallthrough) +#if defined(HAVE_IMPLICIT_FALLTHROUGH) +#define fallthrough __attribute__((__fallthrough__)) +#else +#define fallthrough ((void)0) +#endif +#endif + #if !defined(READ_ONCE) #define READ_ONCE(x) ACCESS_ONCE(x) #endif diff --git a/include/os/linux/zfs/sys/zfs_context_os.h b/include/os/linux/zfs/sys/zfs_context_os.h index 9e5fdd79f0..dc1ac46576 100644 --- a/include/os/linux/zfs/sys/zfs_context_os.h +++ b/include/os/linux/zfs/sys/zfs_context_os.h @@ -26,5 +26,6 @@ #include #include #include +#include #endif diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 9f637036ee..98190079a8 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -759,7 +759,6 @@ extern void spl_fstrans_unmark(fstrans_cookie_t); extern int __spl_pf_fstrans_check(void); extern int kmem_cache_reap_active(void); -#define ____cacheline_aligned /* * Kernel modules diff --git a/lib/libspl/include/sys/feature_tests.h b/lib/libspl/include/sys/feature_tests.h index 1a68b75f0c..a36fd7b8cf 100644 --- a/lib/libspl/include/sys/feature_tests.h +++ b/lib/libspl/include/sys/feature_tests.h @@ -27,6 +27,15 @@ #ifndef _SYS_FEATURE_TESTS_H #define _SYS_FEATURE_TESTS_H -#define __NORETURN __attribute__((__noreturn__)) +#define ____cacheline_aligned +#define __NORETURN __attribute__((__noreturn__)) + +#if !defined(fallthrough) +#if defined(HAVE_IMPLICIT_FALLTHROUGH) +#define fallthrough __attribute__((__fallthrough__)) +#else +#define fallthrough ((void)0) +#endif +#endif #endif diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 688c660f3f..fb420da324 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1365,10 +1365,9 @@ badlabel: (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } + fallthrough; } - /*FALLTHRU*/ - case ZFS_PROP_SHARESMB: case ZFS_PROP_SHARENFS: /* @@ -3767,8 +3766,8 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type, if (type == ZFS_TYPE_VOLUME) return (zfs_error(hdl, EZFS_VOLTOOBIG, errbuf)); + fallthrough; #endif - /* FALLTHROUGH */ default: return (zfs_standard_error(hdl, errno, errbuf)); } diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 3606bbfdd5..f5ea2af243 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -309,7 +309,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, len); break; } - /* FALLTHROUGH */ + fallthrough; default: (void) strlcpy(buf, "-", len); break; @@ -400,7 +400,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, (void) snprintf(buf, len, "-"); break; } - /* FALLTHROUGH */ + fallthrough; default: (void) snprintf(buf, len, "%llu", (u_longlong_t)intval); } diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index 00723ff529..5410b8fae3 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -4883,7 +4883,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, (void) zfs_error(hdl, EZFS_BUSY, errbuf); break; } - /* fallthru */ + fallthrough; default: (void) zfs_standard_error(hdl, ioctl_errno, errbuf); } diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 7c2f84c7a2..3fc2d4accc 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -598,7 +598,7 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err, break; } #endif - /* FALLTHROUGH */ + fallthrough; default: (void) zfs_standard_error(hdl, err, errbuf); } diff --git a/lib/libzfsbootenv/lzbe_device.c b/lib/libzfsbootenv/lzbe_device.c index 670efd8b06..d2664db2c6 100644 --- a/lib/libzfsbootenv/lzbe_device.c +++ b/lib/libzfsbootenv/lzbe_device.c @@ -63,7 +63,7 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device) /* Drop this nvlist */ fnvlist_free(nv); } - /* FALLTHROUGH */ + fallthrough; case lzbe_replace: nv = fnvlist_alloc(); break; diff --git a/module/icp/core/kcf_prov_tabs.c b/module/icp/core/kcf_prov_tabs.c index 94e6937bcd..9d303d0225 100644 --- a/module/icp/core/kcf_prov_tabs.c +++ b/module/icp/core/kcf_prov_tabs.c @@ -377,7 +377,7 @@ kcf_provider_zero_refcnt(kcf_provider_desc_t *desc) mutex_exit(&desc->pd_lock); break; } - /* FALLTHRU */ + fallthrough; case CRYPTO_HW_PROVIDER: case CRYPTO_LOGICAL_PROVIDER: diff --git a/module/icp/io/aes.c b/module/icp/io/aes.c index e540af4473..c47c7567b9 100644 --- a/module/icp/io/aes.c +++ b/module/icp/io/aes.c @@ -976,7 +976,7 @@ aes_encrypt_atomic(crypto_provider_handle_t provider, case AES_GMAC_MECH_INFO_TYPE: if (plaintext->cd_length != 0) return (CRYPTO_ARGUMENTS_BAD); - /* FALLTHRU */ + fallthrough; case AES_GCM_MECH_INFO_TYPE: length_needed = plaintext->cd_length + aes_ctx.ac_tag_len; break; diff --git a/module/lua/lcode.c b/module/lua/lcode.c index ae9a3d91d8..4d88c792a2 100644 --- a/module/lua/lcode.c +++ b/module/lua/lcode.c @@ -8,6 +8,10 @@ #define lcode_c #define LUA_CORE +#if defined(HAVE_IMPLICIT_FALLTHROUGH) +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif + #include #include "lcode.h" diff --git a/module/lua/lgc.c b/module/lua/lgc.c index 55feb24119..227ad723a0 100644 --- a/module/lua/lgc.c +++ b/module/lua/lgc.c @@ -676,7 +676,7 @@ static void freeobj (lua_State *L, GCObject *o) { case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; case LUA_TSHRSTR: G(L)->strt.nuse--; - /* FALLTHROUGH */ + fallthrough; case LUA_TLNGSTR: { luaM_freemem(L, o, sizestring(gco2ts(o))); break; diff --git a/module/lua/llex.c b/module/lua/llex.c index 50c301f599..f2c9bf826c 100644 --- a/module/lua/llex.c +++ b/module/lua/llex.c @@ -477,7 +477,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { else if (!lisdigit(ls->current)) return '.'; /* else go through */ } - /* FALLTHROUGH */ + fallthrough; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { read_numeral(ls, seminfo); diff --git a/module/lua/lstrlib.c b/module/lua/lstrlib.c index 12027757bf..46e3d8fb35 100644 --- a/module/lua/lstrlib.c +++ b/module/lua/lstrlib.c @@ -501,7 +501,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { } case '+': /* 1 or more repetitions */ s++; /* 1 match already done */ - /* FALLTHROUGH */ + fallthrough; case '*': /* 0 or more repetitions */ s = max_expand(ms, s, p, ep); break; diff --git a/module/lua/ltable.c b/module/lua/ltable.c index f60418721b..f6872babc6 100644 --- a/module/lua/ltable.c +++ b/module/lua/ltable.c @@ -492,7 +492,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { return luaH_getint(t, k); /* use specialized version */ /* else go through */ } - /* FALLTHROUGH */ + fallthrough; default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ diff --git a/module/os/freebsd/zfs/zfs_acl.c b/module/os/freebsd/zfs/zfs_acl.c index 7089d0e0e8..9d6e3a5494 100644 --- a/module/os/freebsd/zfs/zfs_acl.c +++ b/module/os/freebsd/zfs/zfs_acl.c @@ -269,7 +269,7 @@ zfs_ace_fuid_size(void *acep) entry_type == OWNING_GROUP || entry_type == ACE_EVERYONE) return (sizeof (zfs_ace_hdr_t)); - /*FALLTHROUGH*/ + fallthrough; default: return (sizeof (zfs_ace_t)); } @@ -2151,7 +2151,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, break; case OWNING_GROUP: who = gowner; - /*FALLTHROUGH*/ + fallthrough; case ACE_IDENTIFIER_GROUP: checkit = zfs_groupmember(zfsvfs, who, cr); break; diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index 59734e63de..8c32386c06 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -974,7 +974,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, cnp->cn_flags |= SAVENAME; break; } - /* FALLTHROUGH */ + fallthrough; case DELETE: if (error == 0) cnp->cn_flags |= SAVENAME; diff --git a/module/os/linux/zfs/zfs_acl.c b/module/os/linux/zfs/zfs_acl.c index f8bf55f75e..cf37aecf8a 100644 --- a/module/os/linux/zfs/zfs_acl.c +++ b/module/os/linux/zfs/zfs_acl.c @@ -269,7 +269,7 @@ zfs_ace_fuid_size(void *acep) entry_type == OWNING_GROUP || entry_type == ACE_EVERYONE) return (sizeof (zfs_ace_hdr_t)); - /*FALLTHROUGH*/ + fallthrough; default: return (sizeof (zfs_ace_t)); } @@ -2317,7 +2317,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, break; case OWNING_GROUP: who = gowner; - /*FALLTHROUGH*/ + fallthrough; case ACE_IDENTIFIER_GROUP: checkit = zfs_groupmember(zfsvfs, who, cr); break; diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c index 9318cc4596..36cdcfa3ba 100644 --- a/module/os/linux/zfs/zfs_znode.c +++ b/module/os/linux/zfs/zfs_znode.c @@ -430,7 +430,7 @@ zfs_inode_set_ops(zfsvfs_t *zfsvfs, struct inode *ip) case S_IFBLK: (void) sa_lookup(ITOZ(ip)->z_sa_hdl, SA_ZPL_RDEV(zfsvfs), &rdev, sizeof (rdev)); - /*FALLTHROUGH*/ + fallthrough; case S_IFIFO: case S_IFSOCK: init_special_inode(ip, ip->i_mode, rdev); diff --git a/module/zfs/abd.c b/module/zfs/abd.c index 1333b2671b..caffe04764 100644 --- a/module/zfs/abd.c +++ b/module/zfs/abd.c @@ -1064,10 +1064,10 @@ abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd, switch (parity) { case 3: len = MIN(caiters[2].iter_mapsize, len); - /* falls through */ + fallthrough; case 2: len = MIN(caiters[1].iter_mapsize, len); - /* falls through */ + fallthrough; case 1: len = MIN(caiters[0].iter_mapsize, len); } @@ -1177,11 +1177,11 @@ abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds, case 3: len = MIN(xiters[2].iter_mapsize, len); len = MIN(citers[2].iter_mapsize, len); - /* falls through */ + fallthrough; case 2: len = MIN(xiters[1].iter_mapsize, len); len = MIN(citers[1].iter_mapsize, len); - /* falls through */ + fallthrough; case 1: len = MIN(xiters[0].iter_mapsize, len); len = MIN(citers[0].iter_mapsize, len); diff --git a/module/zfs/dsl_prop.c b/module/zfs/dsl_prop.c index f6ff9ae471..dfa04d7681 100644 --- a/module/zfs/dsl_prop.c +++ b/module/zfs/dsl_prop.c @@ -749,7 +749,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, ASSERT(err == 0 || err == ENOENT); err = zap_remove(mos, zapobj, inheritstr, tx); ASSERT(err == 0 || err == ENOENT); - /* FALLTHRU */ + fallthrough; case (ZPROP_SRC_NONE | ZPROP_SRC_RECEIVED): /* * remove propname$recvd diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 758710dc9d..8fab480bad 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -9533,7 +9533,7 @@ spa_activity_in_progress(spa_t *spa, zpool_wait_activity_t activity, case ZPOOL_WAIT_RESILVER: if ((*in_progress = vdev_rebuild_active(spa->spa_root_vdev))) break; - /* fall through */ + fallthrough; case ZPOOL_WAIT_SCRUB: { boolean_t scanning, paused, is_scrub; diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c index d063b77ea8..952845cbd8 100644 --- a/module/zfs/vdev_label.c +++ b/module/zfs/vdev_label.c @@ -1288,7 +1288,7 @@ vdev_label_read_bootenv(vdev_t *rvd, nvlist_t *bootenv) nvlist_free(config); break; } - /* FALLTHROUGH */ + fallthrough; default: /* Check for FreeBSD zfs bootonce command string */ buf = abd_to_buf(abd); diff --git a/module/zfs/vdev_raidz_math_scalar.c b/module/zfs/vdev_raidz_math_scalar.c index cd742e146c..9e9c15ff4b 100644 --- a/module/zfs/vdev_raidz_math_scalar.c +++ b/module/zfs/vdev_raidz_math_scalar.c @@ -142,7 +142,7 @@ static const struct { a.b[6] = mul_lt[a.b[6]]; \ a.b[5] = mul_lt[a.b[5]]; \ a.b[4] = mul_lt[a.b[4]]; \ - /* falls through */ \ + fallthrough; \ case 4: \ a.b[3] = mul_lt[a.b[3]]; \ a.b[2] = mul_lt[a.b[2]]; \ diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index cba5e8c9cd..f3d209f1fb 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -362,7 +362,7 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); - /*FALLTHROUGH*/ + fallthrough; case TX_CREATE_ACL_ATTR: if (name == NULL) { lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); @@ -394,7 +394,7 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, lr->lr_uid, lr->lr_gid); - /*FALLTHROUGH*/ + fallthrough; case TX_MKDIR_ACL_ATTR: if (name == NULL) { lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); @@ -519,8 +519,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); name = (char *)start; - - /*FALLTHROUGH*/ + fallthrough; case TX_CREATE: if (name == NULL) name = (char *)start; @@ -537,8 +536,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); name = (char *)start; - - /*FALLTHROUGH*/ + fallthrough; case TX_MKDIR: if (name == NULL) name = (char *)(lr + 1); diff --git a/module/zfs/zio_compress.c b/module/zfs/zio_compress.c index 2db3cec35d..01a18c096f 100644 --- a/module/zfs/zio_compress.c +++ b/module/zfs/zio_compress.c @@ -214,7 +214,7 @@ zio_compress_to_feature(enum zio_compress comp) case ZIO_COMPRESS_ZSTD: return (SPA_FEATURE_ZSTD_COMPRESS); default: - /* fallthru */; + break; } return (SPA_FEATURE_NONE); }