pcm: improve workaround for false -Warray-bounds in pcm_switch_sink

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Thu, 23 Apr 2026 20:43:08 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit d02ad9b749aa751cba741f10039b35f5a6850d07
Author: Aidan MacDonald <[email protected]>
Date:   Fri Apr 24 00:13:25 2026 +0100

    pcm: improve workaround for false -Warray-bounds in pcm_switch_sink
    
    Change-Id: I81ff414ed07bbc61367250c25dc99c11e79d21d2

diff --git a/firmware/include/gcc_extensions.h b/firmware/include/gcc_extensions.h
index ecead8cbb5..3c4f0476a9 100644
--- a/firmware/include/gcc_extensions.h
+++ b/firmware/include/gcc_extensions.h
@@ -77,5 +77,19 @@
 #define UNUSED_ATTR
 #endif
 
+/*
+ * Tell the compiler to assume 'x' is true. With a new enough GCC
+ * there's an attribute for this based on C++23's assume attribute.
+ * On older GCC we need to play tricks with __builtin_unreachable().
+ * As a result 'x' may or may not be evaluated at runtime and should
+ * be side-effect free to ensure it doesn't have any runtime impact.
+ */
+#if defined(__GNUC__) && (__GNUC__ >= 13)
+# define ASSUME(x) __attribute__((assume((x))))
+#elif defined(__GNUC__)
+# define ASSUME(x) do { if(!(x)) __builtin_unreachable(); } while (0)
+#else
+# define ASSUME(x)
+#endif
 
 #endif /* _GCC_EXTENSIONS_H_ */
diff --git a/firmware/pcm.c b/firmware/pcm.c
index 25feed5a49..bb4fd588b5 100644
--- a/firmware/pcm.c
+++ b/firmware/pcm.c
@@ -303,21 +303,24 @@ bool pcm_switch_sink(enum pcm_sink_ids sink)
         return true;
     }
 
-    /* This should not be possible but it silences
-       a false warning that only occurs with with GCC9.5 on bare metal ARM.
-    */
-#if __GNUC__ == 9 && defined(CPU_ARM)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warray-bounds"
-#endif
+    /*
+     * If PCM_SINK_NUM == 1, GCC 9.5 can infer that cur_sink
+     * must be nonzero here (because of the above checks) and
+     * issue a -Warray-bounds warning. This only happens on
+     * some architectures (ARM), and oddly enough, only when
+     * cur_sink is an enum type.
+     *
+     * Since this situation isn't possible outside of memory
+     * corruption we can just tell the compiler to assume it
+     * can't happen. This avoids the warning, and saves a bit
+     * of code size since none of the code below is reachable
+     * when there's only one PCM sink.
+     */
+    ASSUME(cur_sink < PCM_SINK_NUM);
 
     /* save current sink before switching */
     struct pcm_sink* old_sink = sinks[cur_sink];
 
-#if __GNUC__ == 9
-#pragma GCC diagnostic pop
-#endif
-
     /* update sink index */
     cur_sink = sink;
     /* synchronize frequency */
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs