diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 4ebe25461a..293ee86ea4 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -49,7 +49,8 @@ __thread uintptr_t helper_retaddr; /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ -static void cpu_exit_tb_from_sighandler(CPUState *cpu, sigset_t *old_set) +static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu, + sigset_t *old_set) { /* XXX: use siglongjmp ? */ sigprocmask(SIG_SETMASK, old_set, NULL); diff --git a/bsd-user/main.c b/bsd-user/main.c index 0a918e8f74..9c700c6234 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -512,6 +512,7 @@ void cpu_loop(CPUSPARCState *env) case 0x141: if (bsd_type != target_freebsd) goto badtrap; + /* fallthrough */ case 0x100: #endif syscall_nr = env->gregs[1]; diff --git a/configure b/configure index c228f7c21e..881af4b6be 100755 --- a/configure +++ b/configure @@ -2023,6 +2023,7 @@ add_to warn_flags -Wempty-body add_to warn_flags -Wnested-externs add_to warn_flags -Wendif-labels add_to warn_flags -Wexpansion-to-defined +add_to warn_flags -Wimplicit-fallthrough=2 nowarn_flags= add_to nowarn_flags -Wno-initializer-overrides diff --git a/disas/libvixl/vixl/a64/disasm-a64.cc b/disas/libvixl/vixl/a64/disasm-a64.cc index 7a58a5c087..f34d1d68da 100644 --- a/disas/libvixl/vixl/a64/disasm-a64.cc +++ b/disas/libvixl/vixl/a64/disasm-a64.cc @@ -2985,6 +2985,10 @@ int Disassembler::SubstituteImmediateField(const Instruction* instr, } return 3; } + default: { + VIXL_UNIMPLEMENTED(); + return 0; + } } } case 'C': { // ICondB - Immediate Conditional Branch. diff --git a/disas/libvixl/vixl/globals.h b/disas/libvixl/vixl/globals.h index 61dc9f7f7e..7099aa599f 100644 --- a/disas/libvixl/vixl/globals.h +++ b/disas/libvixl/vixl/globals.h @@ -108,10 +108,12 @@ inline void USE(T1, T2, T3, T4) {} #define __has_warning(x) 0 #endif -// Note: This option is only available for Clang. And will only be enabled for -// C++11(201103L). +// Fallthrough annotation for Clang and C++11(201103L). #if __has_warning("-Wimplicit-fallthrough") && __cplusplus >= 201103L #define VIXL_FALLTHROUGH() [[clang::fallthrough]] //NOLINT +// Fallthrough annotation for GCC >= 7. +#elif __GNUC__ >= 7 + #define VIXL_FALLTHROUGH() __attribute__((fallthrough)) #else #define VIXL_FALLTHROUGH() do {} while (0) #endif diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 187eb054e0..d040a5d1e9 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -478,9 +478,11 @@ static void kvm_arm_gicv3_put(GICv3State *s) kvm_gicc_access(s, ICC_AP0R_EL1(3), ncpu, ®64, true); reg64 = c->icc_apr[GICV3_G0][2]; kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, ®64, true); + /* fall through */ case 6: reg64 = c->icc_apr[GICV3_G0][1]; kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, ®64, true); + /* fall through */ default: reg64 = c->icc_apr[GICV3_G0][0]; kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, ®64, true); @@ -492,9 +494,11 @@ static void kvm_arm_gicv3_put(GICv3State *s) kvm_gicc_access(s, ICC_AP1R_EL1(3), ncpu, ®64, true); reg64 = c->icc_apr[GICV3_G1NS][2]; kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, ®64, true); + /* fall through */ case 6: reg64 = c->icc_apr[GICV3_G1NS][1]; kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, ®64, true); + /* fall through */ default: reg64 = c->icc_apr[GICV3_G1NS][0]; kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, ®64, true); @@ -631,9 +635,11 @@ static void kvm_arm_gicv3_get(GICv3State *s) c->icc_apr[GICV3_G0][3] = reg64; kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, ®64, false); c->icc_apr[GICV3_G0][2] = reg64; + /* fall through */ case 6: kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, ®64, false); c->icc_apr[GICV3_G0][1] = reg64; + /* fall through */ default: kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, ®64, false); c->icc_apr[GICV3_G0][0] = reg64; @@ -645,9 +651,11 @@ static void kvm_arm_gicv3_get(GICv3State *s) c->icc_apr[GICV3_G1NS][3] = reg64; kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, ®64, false); c->icc_apr[GICV3_G1NS][2] = reg64; + /* fall through */ case 6: kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, ®64, false); c->icc_apr[GICV3_G1NS][1] = reg64; + /* fall through */ default: kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, ®64, false); c->icc_apr[GICV3_G1NS][0] = reg64; diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c index f838913b37..006d75e174 100644 --- a/hw/rtc/twl92230.c +++ b/hw/rtc/twl92230.c @@ -271,37 +271,23 @@ static void menelaus_gpio_set(void *opaque, int line, int level) static uint8_t menelaus_read(void *opaque, uint8_t addr) { MenelausState *s = (MenelausState *) opaque; - int reg = 0; switch (addr) { case MENELAUS_REV: return 0x22; - case MENELAUS_VCORE_CTRL5: reg ++; - case MENELAUS_VCORE_CTRL4: reg ++; - case MENELAUS_VCORE_CTRL3: reg ++; - case MENELAUS_VCORE_CTRL2: reg ++; - case MENELAUS_VCORE_CTRL1: - return s->vcore[reg]; + case MENELAUS_VCORE_CTRL1 ... MENELAUS_VCORE_CTRL5: + return s->vcore[addr - MENELAUS_VCORE_CTRL1]; - case MENELAUS_DCDC_CTRL3: reg ++; - case MENELAUS_DCDC_CTRL2: reg ++; - case MENELAUS_DCDC_CTRL1: - return s->dcdc[reg]; + case MENELAUS_DCDC_CTRL1 ... MENELAUS_DCDC_CTRL3: + return s->dcdc[addr - MENELAUS_DCDC_CTRL1]; - case MENELAUS_LDO_CTRL8: reg ++; - case MENELAUS_LDO_CTRL7: reg ++; - case MENELAUS_LDO_CTRL6: reg ++; - case MENELAUS_LDO_CTRL5: reg ++; - case MENELAUS_LDO_CTRL4: reg ++; - case MENELAUS_LDO_CTRL3: reg ++; - case MENELAUS_LDO_CTRL2: reg ++; - case MENELAUS_LDO_CTRL1: - return s->ldo[reg]; + case MENELAUS_LDO_CTRL1 ... MENELAUS_LDO_CTRL8: + return s->ldo[addr - MENELAUS_LDO_CTRL1]; - case MENELAUS_SLEEP_CTRL2: reg ++; case MENELAUS_SLEEP_CTRL1: - return s->sleep[reg]; + case MENELAUS_SLEEP_CTRL2: + return s->sleep[addr - MENELAUS_SLEEP_CTRL1]; case MENELAUS_DEVICE_OFF: return 0; @@ -395,10 +381,8 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr) case MENELAUS_S2_PULL_DIR: return s->pull[3]; - case MENELAUS_MCT_CTRL3: reg ++; - case MENELAUS_MCT_CTRL2: reg ++; - case MENELAUS_MCT_CTRL1: - return s->mmc_ctrl[reg]; + case MENELAUS_MCT_CTRL1 ... MENELAUS_MCT_CTRL3: + return s->mmc_ctrl[addr - MENELAUS_MCT_CTRL1]; case MENELAUS_MCT_PIN_ST: /* TODO: return the real Card Detect */ return 0; @@ -418,7 +402,6 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) { MenelausState *s = (MenelausState *) opaque; int line; - int reg = 0; struct tm tm; switch (addr) { @@ -496,9 +479,9 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) s->ldo[7] = value & 3; break; - case MENELAUS_SLEEP_CTRL2: reg ++; case MENELAUS_SLEEP_CTRL1: - s->sleep[reg] = value; + case MENELAUS_SLEEP_CTRL2: + s->sleep[addr - MENELAUS_SLEEP_CTRL1] = value; break; case MENELAUS_DEVICE_OFF: @@ -714,6 +697,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) #ifdef VERBOSE printf("%s: unknown register %02x\n", __func__, addr); #endif + break; } } diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c index 446f2eacdd..e03a8155b2 100644 --- a/hw/timer/renesas_tmr.c +++ b/hw/timer/renesas_tmr.c @@ -221,6 +221,7 @@ static uint64_t tmr_read(void *opaque, hwaddr addr, unsigned size) } else if (ch == 0) { return concat_reg(tmr->tcora); } + /* fall through */ case A_TCORB: if (size == 1) { return tmr->tcorb[ch]; diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 1b9e58e82b..df9ec08f8a 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -222,4 +222,15 @@ extern void QEMU_NORETURN QEMU_ERROR("code path is reachable") #define qemu_build_not_reached() g_assert_not_reached() #endif +/** + * In most cases, normal "fallthrough" comments are good enough for + * switch-case statements, but sometimes the compiler has problems + * with those. In that case you can use QEMU_FALLTHROUGH instead. + */ +#if __has_attribute(fallthrough) +# define QEMU_FALLTHROUGH __attribute__((fallthrough)) +#else +# define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */ +#endif + #endif /* COMPILER_H */ diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 750f75c257..11db2f3c8d 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -1778,9 +1778,12 @@ static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1, } else { tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); } - /* FALLTHRU */ -#ifdef TARGET_X86_64 + /* + * If TARGET_X86_64 defined then fall through into MO_32 case, + * otherwise fall through default case. + */ case MO_32: +#ifdef TARGET_X86_64 /* Concatenate the two 32-bit values and use a 64-bit shift. */ tcg_gen_subi_tl(s->tmp0, count, 1); if (is_right) { diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 30c73f8d2e..4bfa3179f8 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -2324,8 +2324,8 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, } /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions * are ST_BLKINIT_ ASIs */ - /* fall through */ #endif + /* fall through */ case GET_ASI_DIRECT: gen_address_mask(dc, addr); tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop); diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 5b57892a10..3a7c0ff943 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -302,7 +302,7 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) switch (pstate) { default: trace_win_helper_gregset_error(pstate); - /* pass through to normal set of global registers */ + /* fall through to normal set of global registers */ case 0: return env->bgregs; case PS_AG: diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c index d4b06df672..962f9877a0 100644 --- a/target/unicore32/translate.c +++ b/target/unicore32/translate.c @@ -1801,6 +1801,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) do_misc(env, s, insn); break; } + /* fallthrough */ case 0x1: if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) { do_misc(env, s, insn); @@ -1817,6 +1818,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) if (UCOP_SET(8) || UCOP_SET(5)) { ILLEGAL; } + /* fallthrough */ case 0x3: do_ldst_ir(env, s, insn); break; diff --git a/tcg/optimize.c b/tcg/optimize.c index 220f4601d5..7ca71de956 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -855,6 +855,7 @@ void tcg_optimize(TCGContext *s) if ((arg_info(op->args[1])->mask & 0x80) != 0) { break; } + QEMU_FALLTHROUGH; CASE_OP_32_64(ext8u): mask = 0xff; goto and_const; @@ -862,6 +863,7 @@ void tcg_optimize(TCGContext *s) if ((arg_info(op->args[1])->mask & 0x8000) != 0) { break; } + QEMU_FALLTHROUGH; CASE_OP_32_64(ext16u): mask = 0xffff; goto and_const; @@ -869,6 +871,7 @@ void tcg_optimize(TCGContext *s) if ((arg_info(op->args[1])->mask & 0x80000000) != 0) { break; } + QEMU_FALLTHROUGH; case INDEX_op_ext32u_i64: mask = 0xffffffffU; goto and_const; @@ -886,6 +889,7 @@ void tcg_optimize(TCGContext *s) if ((arg_info(op->args[1])->mask & 0x80000000) != 0) { break; } + QEMU_FALLTHROUGH; case INDEX_op_extu_i32_i64: /* We do not compute affected as it is a size changing op. */ mask = (uint32_t)arg_info(op->args[1])->mask; diff --git a/tests/fp/meson.build b/tests/fp/meson.build index 3d4fb00f9d..8d739c4d59 100644 --- a/tests/fp/meson.build +++ b/tests/fp/meson.build @@ -27,6 +27,7 @@ tfdir = 'berkeley-testfloat-3/source' sfinc = include_directories(sfdir / 'include', sfspedir) tfcflags = [ + '-Wno-implicit-fallthrough', '-Wno-strict-prototypes', '-Wno-unknown-pragmas', '-Wno-uninitialized', @@ -209,6 +210,7 @@ libtestfloat = static_library( ) sfcflags = [ + '-Wno-implicit-fallthrough', '-Wno-missing-prototypes', '-Wno-redundant-decls', '-Wno-return-type',