diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2333ef4d4..d8eb6dc01 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -41,11 +41,11 @@ jobs:
             cxx: g++-14
             packages: g++-14
             meson_options:
-          - compiler: gcc10
+          - compiler: gcc12
             os: ubuntu-24.04
-            cc: gcc-10
-            cxx: g++-10
-            packages: g++-10
+            cc: gcc-12
+            cxx: g++-12
+            packages: g++-12
             meson_options:
           - compiler: clang
             os: ubuntu-24.04
diff --git a/NEWS b/NEWS
index 112b9d7c1..511001e5c 100644
--- a/NEWS
+++ b/NEWS
@@ -58,7 +58,7 @@ ver 0.24 (not yet released)
   - alsa: require alsa-lib 1.1 or later
   - pipewire: map tags "Date" and "Comment"
 * switch to C++20
-  - GCC 10 or clang 11 (or newer) recommended
+  - GCC 12 or clang 14 (or newer) recommended
 * static partition configuration
 * Windows
   - build with libsamplerate
diff --git a/doc/developer.rst b/doc/developer.rst
index 5f8f2550e..8269e837c 100644
--- a/doc/developer.rst
+++ b/doc/developer.rst
@@ -12,7 +12,7 @@ Code Style
 * indent with tabs (width 8)
 * don't write CPP when you can write C++: use inline functions and constexpr instead of macros
 * comment your code, document your APIs
-* the code should be C++20 compliant, and must compile with :program:`GCC` 10 and :program:`clang` 11
+* the code should be C++20 compliant, and must compile with :program:`GCC` 12 and :program:`clang` 14
 * all code must be exception-safe
 * classes and functions names use CamelCase; variables are lower-case with words separated by underscore
 
diff --git a/doc/user.rst b/doc/user.rst
index 7406ad777..fbe30442e 100644
--- a/doc/user.rst
+++ b/doc/user.rst
@@ -57,7 +57,7 @@ and unpack it (or `clone the git repository
 
 In any case, you need:
 
-* a C++20 compiler (e.g. GCC 10 or clang 11)
+* a C++20 compiler (e.g. GCC 12 or clang 14)
 * `Meson 1.0 <http://mesonbuild.com/>`__ and `Ninja
   <https://ninja-build.org/>`__
 * pkg-config 
diff --git a/meson.build b/meson.build
index c71cb3354..204afd137 100644
--- a/meson.build
+++ b/meson.build
@@ -102,10 +102,10 @@ version_cxx = vcs_tag(input: 'src/GitVersion.cxx', output: 'GitVersion.cxx')
 compiler = meson.get_compiler('cpp')
 c_compiler = meson.get_compiler('c')
 
-if compiler.get_id() == 'gcc' and compiler.version().version_compare('<10')
-  warning('Your GCC version is too old.  You need at least version 10.')
-elif compiler.get_id() == 'clang' and compiler.version().version_compare('<11')
-  warning('Your clang version is too old.  You need at least version 11.')
+if compiler.get_id() == 'gcc' and compiler.version().version_compare('<12')
+  warning('Your GCC version is too old.  You need at least version 12.')
+elif compiler.get_id() == 'clang' and compiler.version().version_compare('<14')
+  warning('Your clang version is too old.  You need at least version 14.')
 endif
 
 version_conf = configuration_data()
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index 67fd413a3..b7a14e260 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -662,11 +662,6 @@ MadDecoder::DecodeFirstFrame(Tag *tag) noexcept
 {
 	struct xing xing;
 
-#if GCC_CHECK_VERSION(10,0)
-	/* work around bogus -Wuninitialized in GCC 10 */
-	xing.frames = 0;
-#endif
-
 	while (true) {
 		const auto action = DecodeNextFrame(false, tag);
 		switch (action) {