SDL: cmake: add -Wimplicit-fallthrough warning

From f59dbf6a1204552fdfeab7f3b156e5606ebb206a Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 18 Mar 2024 17:56:22 +0100
Subject: [PATCH] cmake: add -Wimplicit-fallthrough warning

---
 cmake/sdlcompilers.cmake                 | 5 +++++
 src/core/freebsd/SDL_evdev_kbd_freebsd.c | 3 +++
 src/events/SDL_pen.c                     | 1 +
 src/joystick/linux/SDL_sysjoystick.c     | 2 ++
 src/video/vita/SDL_vitavideo.c           | 1 +
 test/testautomation_audio.c              | 1 +
 test/testautomation_pen.c                | 4 ++--
 test/testcolorspace.c                    | 1 +
 test/testoverlay.c                       | 1 +
 test/testsurround.c                      | 9 +++++----
 10 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/cmake/sdlcompilers.cmake b/cmake/sdlcompilers.cmake
index 81b5f836907d9..5138fdd0b19fe 100644
--- a/cmake/sdlcompilers.cmake
+++ b/cmake/sdlcompilers.cmake
@@ -105,6 +105,11 @@ function(SDL_AddCommonCompilerFlags TARGET)
     if(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS)
       sdl_target_compile_option_all_languages(${TARGET} "-Wno-unused-local-typedefs")
     endif()
+
+    check_c_compiler_flag(-Wimplicit-fallthrough HAVE_GCC_WIMPLICIT_FALLTHROUGH)
+    if(HAVE_GCC_WIMPLICIT_FALLTHROUGH)
+      sdl_target_compile_option_all_languages(${TARGET} "-Wimplicit-fallthrough")
+    endif()
   endif()
 
   if(SDL_WERROR)
diff --git a/src/core/freebsd/SDL_evdev_kbd_freebsd.c b/src/core/freebsd/SDL_evdev_kbd_freebsd.c
index 2c1df4a8d2297..22d02bf5452e7 100644
--- a/src/core/freebsd/SDL_evdev_kbd_freebsd.c
+++ b/src/core/freebsd/SDL_evdev_kbd_freebsd.c
@@ -542,6 +542,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
                 if (down == 0) {
                     chg_vc_kbd_led(kbd, ALKED);
                 }
+                SDL_FALLTHROUGH;
             case LSH: /* left shift */
             case RSH: /* right shift */
                 k_shift(kbd, 0, down == 0);
@@ -551,6 +552,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
                 if (down == 0) {
                     chg_vc_kbd_led(kbd, ALKED);
                 }
+                SDL_FALLTHROUGH;
             case LCTR: /* left ctrl */
             case RCTR: /* right ctrl */
                 k_shift(kbd, 1, down == 0);
@@ -560,6 +562,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
                 if (down == 0) {
                     chg_vc_kbd_led(kbd, ALKED);
                 }
+                SDL_FALLTHROUGH;
             case LALT: /* left alt */
             case RALT: /* right alt */
                 k_shift(kbd, 2, down == 0);
diff --git a/src/events/SDL_pen.c b/src/events/SDL_pen.c
index 216827b22b3bc..43ec94921e275 100644
--- a/src/events/SDL_pen.c
+++ b/src/events/SDL_pen.c
@@ -573,6 +573,7 @@ int SDL_SendPenMotion(Uint64 timestamp,
                 event.motion.yrel = last_y - y;
                 return (SDL_PushEvent(&event) > 0) || posted;
             }
+            break;
 
         default:
             break;
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index 5de8b758177a8..eeefa69d15584 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -2005,6 +2005,7 @@ static void HandleInputEvents(SDL_Joystick *joystick)
                 default:
                     break;
                 }
+                break;
             default:
                 break;
             }
@@ -2095,6 +2096,7 @@ static void HandleInputEvents(SDL_Joystick *joystick)
                     default:
                         break;
                     }
+                    break;
                 default:
                     break;
                 }
diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c
index bed1954776a5b..480ffd88ad34e 100644
--- a/src/video/vita/SDL_vitavideo.c
+++ b/src/video/vita/SDL_vitavideo.c
@@ -404,6 +404,7 @@ void VITA_ImeEventHandler(void *arg, const SceImeEventData *e)
         break;
     case SCE_IME_EVENT_PRESS_ENTER:
         SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN);
+        break;
     case SCE_IME_EVENT_PRESS_CLOSE:
         sceImeClose();
         videodata->ime_active = SDL_FALSE;
diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c
index 7b46598615a53..3daa2d8a100c5 100644
--- a/test/testautomation_audio.c
+++ b/test/testautomation_audio.c
@@ -188,6 +188,7 @@ static int audio_initOpenCloseQuitAudio(void *arg)
                 desired.freq = 22050;
                 desired.format = SDL_AUDIO_S16;
                 desired.channels = 2;
+                break;
 
             case 1:
                 /* Set custom desired spec */
diff --git a/test/testautomation_pen.c b/test/testautomation_pen.c
index e0918def9be97..f5c3bff981417 100644
--- a/test/testautomation_pen.c
+++ b/test/testautomation_pen.c
@@ -1383,7 +1383,7 @@ pen_movementAndAxes(void *arg)
         case SIMPEN_ACTION_PRESS:
             SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_BUTTON_DOWN, "Expected PENBUTTONDOWN event (but got 0x%lx)", (unsigned long) event.type);
             SDLTest_AssertCheck(event.pbutton.state == SDL_PRESSED, "Expected PRESSED button");
-            /* Fall through */
+            SDL_FALLTHROUGH;
         case SIMPEN_ACTION_RELEASE:
             if (last_action->type == SIMPEN_ACTION_RELEASE) {
                 SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_BUTTON_UP, "Expected PENBUTTONUP event (but got 0x%lx)", (unsigned long) event.type);
@@ -1401,7 +1401,7 @@ pen_movementAndAxes(void *arg)
         case SIMPEN_ACTION_DOWN:
             SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_DOWN, "Expected PENBUTTONDOWN event (but got 0x%lx)", (unsigned long) event.type);
             SDLTest_AssertCheck(event.ptip.state == SDL_PRESSED, "Expected PRESSED button");
-            /* Fall through */
+            SDL_FALLTHROUGH;
         case SIMPEN_ACTION_UP:
             if (last_action->type == SIMPEN_ACTION_UP) {
                 SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_UP, "Expected PENBUTTONUP event (but got 0x%lx)", (unsigned long) event.type);
diff --git a/test/testcolorspace.c b/test/testcolorspace.c
index ee1c610b1e4ff..21bfe9a13e17c 100644
--- a/test/testcolorspace.c
+++ b/test/testcolorspace.c
@@ -508,6 +508,7 @@ static void loop(void)
             switch (event.key.keysym.sym) {
             case SDLK_ESCAPE:
                 done = 1;
+                break;
             case SDLK_SPACE:
             case SDLK_RIGHT:
                 NextStage();
diff --git a/test/testoverlay.c b/test/testoverlay.c
index 110617787206b..81a73b5d0213d 100644
--- a/test/testoverlay.c
+++ b/test/testoverlay.c
@@ -282,6 +282,7 @@ static void loop(void)
             if (event.key.keysym.sym != SDLK_ESCAPE) {
                 break;
             }
+            break;
         default:
             break;
         }
diff --git a/test/testsurround.c b/test/testsurround.c
index ea27cb172824a..d0aa3d0a95515 100644
--- a/test/testsurround.c
+++ b/test/testsurround.c
@@ -65,7 +65,7 @@ get_channel_name(int channel_index, int channel_count)
         case 8:
             return "Back Left";
         }
-        SDL_assert(0);
+        break;
     case 5:
         switch (channel_count) {
         case 6:
@@ -75,7 +75,7 @@ get_channel_name(int channel_index, int channel_count)
         case 8:
             return "Back Right";
         }
-        SDL_assert(0);
+        break;
     case 6:
         switch (channel_count) {
         case 7:
@@ -83,11 +83,12 @@ get_channel_name(int channel_index, int channel_count)
         case 8:
             return "Side Left";
         }
-        SDL_assert(0);
+        break;
     case 7:
         return "Side Right";
     }
-
+    SDLTest_AssertCheck(SDL_FALSE, "Invalid channel_index for channel_count:  channel_count=%d channel_index=%d", channel_count, channel_index);
+    SDL_assert(0);
     return NULL;
 }