[libcxx] [libcxxabi] [llvm] [libc++] Upgrade to GCC 16 (PR #206235)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 01:34:55 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/206235

>From dbf598903d79b5885b0bd68df3e13224562ccc2d Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 27 Jun 2026 11:11:40 +0200
Subject: [PATCH] [libc++] Upgrade to GCC16

---
 .github/workflows/libcxx-pr-conformance-tests.yaml    |  8 ++++----
 libcxx/docs/index.rst                                 |  2 +-
 libcxx/include/__configuration/compiler.h             |  4 ++--
 libcxx/include/__functional/boyer_moore_searcher.h    |  3 +++
 libcxx/include/__functional/weak_result_type.h        | 11 ++++++++---
 libcxx/include/__ranges/concat_view.h                 |  5 ++---
 libcxx/src/experimental/time_zone.cpp                 |  6 ------
 .../libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp |  2 +-
 .../libcxx/type_traits/desugars_to.compile.pass.cpp   |  2 +-
 .../refwrap/desugars_to.compile.pass.cpp              |  2 +-
 .../utilities/meta/is_within_lifetime.verify.cpp      |  1 -
 .../try_emplace_transparent.pass.cpp                  |  2 --
 .../depr/depr.c.headers/stdalign_h.compile.pass.cpp   |  3 ---
 .../expected.expected/monadic/transform.pass.cpp      |  2 +-
 .../monadic/transform_error.pass.cpp                  |  2 +-
 .../expected.void/monadic/transform_error.pass.cpp    |  2 +-
 .../formatter.char_array.pass.cpp                     |  2 +-
 .../is_within_lifetime.compile.pass.cpp               |  2 +-
 .../meta.unary.prop/is_implicit_lifetime.pass.cpp     |  5 ++---
 .../op_subscript.runtime.pass.cpp                     |  3 +++
 .../PR27684_contains_ref_to_incomplete_type.pass.cpp  |  3 +++
 .../tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp    |  2 +-
 .../utility/pairs/pairs.pair/assign_pair.pass.cpp     |  9 ---------
 .../test/catch_member_function_pointer_02.pass.cpp    |  2 +-
 24 files changed, 38 insertions(+), 47 deletions(-)

diff --git a/.github/workflows/libcxx-pr-conformance-tests.yaml b/.github/workflows/libcxx-pr-conformance-tests.yaml
index a7a93a110428c..57424dc0a4936 100644
--- a/.github/workflows/libcxx-pr-conformance-tests.yaml
+++ b/.github/workflows/libcxx-pr-conformance-tests.yaml
@@ -52,8 +52,8 @@ jobs:
         cxx: [ 'clang++-23' ]
         include:
           - config: 'generic-gcc'
-            cc: 'gcc-15'
-            cxx: 'g++-15'
+            cc: 'gcc-16'
+            cxx: 'g++-16'
     steps:
       - uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
         with:
@@ -97,8 +97,8 @@ jobs:
         cxx: [ 'clang++-23' ]
         include:
           - config: 'generic-gcc-cxx11'
-            cc: 'gcc-15'
-            cxx: 'g++-15'
+            cc: 'gcc-16'
+            cxx: 'g++-16'
           - config: 'generic-cxx26'
             cc: 'clang-22'
             cxx: 'clang++-22'
diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst
index 403ce9ca0f254..610fab850924a 100644
--- a/libcxx/docs/index.rst
+++ b/libcxx/docs/index.rst
@@ -136,7 +136,7 @@ Compiler     Versions            Restrictions               Support policy
 Clang        21, 22, 23-git                                 latest two stable releases per `LLVM's release page <https://releases.llvm.org>`_ and the development version
 AppleClang   26.4                                           latest stable release per `Xcode's release page <https://developer.apple.com/documentation/xcode-release-notes>`_
 Open XL      17.1.4 (AIX)                                   latest stable release per `Open XL's documentation page <https://www.ibm.com/docs/en/openxl-c-and-cpp-aix>`_
-GCC          15                  In C++11 or later only     latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
+GCC          16                  In C++11 or later only     latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
 ============ =================== ========================== =====================
 
 Libc++ also supports common platforms and architectures:
diff --git a/libcxx/include/__configuration/compiler.h b/libcxx/include/__configuration/compiler.h
index 264b713d94b6a..2c9b4b294dd45 100644
--- a/libcxx/include/__configuration/compiler.h
+++ b/libcxx/include/__configuration/compiler.h
@@ -41,8 +41,8 @@
 #      warning "Libc++ only supports AppleClang 26.4 and later"
 #    endif
 #  elif defined(_LIBCPP_GCC_VER)
-#    if _LIBCPP_GCC_VER < 1500
-#      warning "Libc++ only supports GCC 15 and later"
+#    if _LIBCPP_GCC_VER < 1600
+#      warning "Libc++ only supports GCC 16 and later"
 #    endif
 #  endif
 
diff --git a/libcxx/include/__functional/boyer_moore_searcher.h b/libcxx/include/__functional/boyer_moore_searcher.h
index 6c51c32d2f89b..2f14cbd99eb22 100644
--- a/libcxx/include/__functional/boyer_moore_searcher.h
+++ b/libcxx/include/__functional/boyer_moore_searcher.h
@@ -71,7 +71,10 @@ class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
 
 public:
   _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable(size_t, value_type __default_value, _Hash, _BinaryPredicate) {
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wmaybe-uninitialized")
     std::fill_n(__table_.data(), __table_.size(), __default_value);
+    _LIBCPP_DIAGNOSTIC_POP
   }
 
   _LIBCPP_HIDE_FROM_ABI void insert(key_type __key, value_type __val) {
diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h
index 4232bdc69dd00..f2159b012d6cc 100644
--- a/libcxx/include/__functional/weak_result_type.h
+++ b/libcxx/include/__functional/weak_result_type.h
@@ -71,13 +71,18 @@ struct __maybe_derive_from_binary_function // bool is true
 template <class _Tp>
 struct __maybe_derive_from_binary_function<_Tp, false> {};
 
-template <class _Tp, bool = __has_result_type_v<_Tp> >
+template <class _Tp,
+          bool =
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+              __has_result_type_v<_Tp>
+#else
+              false
+#endif
+          >
 struct __weak_result_type_imp // bool is true
     : public __maybe_derive_from_unary_function<_Tp>,
       public __maybe_derive_from_binary_function<_Tp> {
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
   using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type;
-#endif
 };
 
 template <class _Tp>
diff --git a/libcxx/include/__ranges/concat_view.h b/libcxx/include/__ranges/concat_view.h
index 3bbe9db12e0f8..41fd8cd216c3f 100644
--- a/libcxx/include/__ranges/concat_view.h
+++ b/libcxx/include/__ranges/concat_view.h
@@ -289,9 +289,8 @@ class concat_view<_Views...>::__iterator : public __concat_view_iterator_categor
 
   template <typename _Func>
   _LIBCPP_HIDE_FROM_ABI constexpr auto __invoke_at_index(_Func&& __func) const {
-    // TODO(GCC 16): Just capture `this` when GCC PR113563 and PR121008 are fixed.
-    return [&__func, &__view_iter = *this]<std::size_t _Is>(this auto&& __self) {
-      if (_Is == __view_iter.__it_.index()) {
+    return [&__func, this]<std::size_t _Is>(this auto&& __self) {
+      if (_Is == __it_.index()) {
         return __func.template operator()<_Is>();
       }
       if constexpr (_Is + 1 < sizeof...(_Views)) {
diff --git a/libcxx/src/experimental/time_zone.cpp b/libcxx/src/experimental/time_zone.cpp
index fc7a9c26c91b2..8c7f24094003d 100644
--- a/libcxx/src/experimental/time_zone.cpp
+++ b/libcxx/src/experimental/time_zone.cpp
@@ -32,12 +32,6 @@
 // Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120502
 
 #include <__config>
-
-// TODO(LLVM 23): When upgrading to GCC 16 this can be removed
-#ifdef _LIBCPP_COMPILER_GCC
-#  pragma GCC optimize("-O0")
-#endif
-
 #include <algorithm>
 #include <cctype>
 #include <chrono>
diff --git a/libcxx/test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp b/libcxx/test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp
index 601c6c2d2cdc3..abd29359ac87c 100644
--- a/libcxx/test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp
+++ b/libcxx/test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp
@@ -12,7 +12,7 @@
 
 // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
 
-// XFAIL: gcc
+// XFAIL: gcc-16
 // UNSUPPORTED: c++03
 
 #include <memory>
diff --git a/libcxx/test/libcxx/type_traits/desugars_to.compile.pass.cpp b/libcxx/test/libcxx/type_traits/desugars_to.compile.pass.cpp
index e28dbd8fa9ff2..0242fe4c42f80 100644
--- a/libcxx/test/libcxx/type_traits/desugars_to.compile.pass.cpp
+++ b/libcxx/test/libcxx/type_traits/desugars_to.compile.pass.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // This test requires variable templates
-// UNSUPPORTED: gcc && c++11
+// ADDITIONAL_COMPILE_FLAGS: -Wno-c++14-extensions
 
 #include <__type_traits/desugars_to.h>
 #include <__algorithm/comp.h>
diff --git a/libcxx/test/libcxx/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp b/libcxx/test/libcxx/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
index aa6bf85a1a40d..f76c266aa5a50 100644
--- a/libcxx/test/libcxx/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
+++ b/libcxx/test/libcxx/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // This test requires variable templates
-// UNSUPPORTED: gcc && c++11
+// ADDITIONAL_COMPILE_FLAGS: -Wno-c++14-extensions
 
 // <functional>
 
diff --git a/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp b/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp
index 0aa0f226d63ca..7ed08ee0894a6 100644
--- a/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp
+++ b/libcxx/test/libcxx/utilities/meta/is_within_lifetime.verify.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-// UNSUPPORTED: gcc-15
 
 // <type_traits>
 
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp
index 6a536d4d8282c..619b6e09ebccd 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp
@@ -7,8 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// gcc 15 ICE on this test
-// UNSUPPORTED: gcc
 
 // <flat_map>
 
diff --git a/libcxx/test/std/depr/depr.c.headers/stdalign_h.compile.pass.cpp b/libcxx/test/std/depr/depr.c.headers/stdalign_h.compile.pass.cpp
index e7290aab2c661..4b1fc4214cbd6 100644
--- a/libcxx/test/std/depr/depr.c.headers/stdalign_h.compile.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/stdalign_h.compile.pass.cpp
@@ -11,9 +11,6 @@
 // Even though <stdalign.h> is not provided by libc++,
 // we still test that using it with libc++ on the search path will work.
 
-// TODO: GCC doesn't provide a proper <stdalign.h> for C++ until 15.
-// UNSUPPORTED: gcc
-
 #include <stdalign.h>
 
 #ifndef __alignas_is_defined
diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp
index 8f63d57af7dee..e1b3a373a7586 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp
@@ -10,7 +10,7 @@
 
 // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`,
 // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98995
-// XFAIL: gcc-15
+// XFAIL: gcc-16
 
 // <expected>
 
diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
index babc813cdd2fe..ea91ee66b943f 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
@@ -10,7 +10,7 @@
 
 // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`,
 // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98995.
-// XFAIL: gcc-15
+// XFAIL: gcc-16
 
 // <expected>
 
diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp
index f0ec946a053d9..b279a5b20fafa 100644
--- a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp
@@ -10,7 +10,7 @@
 
 // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`,
 // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98995
-// XFAIL: gcc-15
+// XFAIL: gcc-16
 
 // <expected>
 
diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp
index 7c0499d091542..4038d91e0d950 100644
--- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp
@@ -8,7 +8,7 @@
 
 // UNSUPPORTED: c++03, c++11, c++14, c++17
 // TODO FMT __builtin_memcpy isn't constexpr in GCC
-// UNSUPPORTED: gcc-15
+// UNSUPPORTED: gcc-16
 
 // <format>
 
diff --git a/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp
index f97b400f9a781..901e212938ffb 100644
--- a/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp
+++ b/libcxx/test/std/utilities/meta/meta.const.eval/is_within_lifetime.compile.pass.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-// UNSUPPORTED: gcc-15
+// UNSUPPORTED: gcc-16
 
 // <type_traits>
 
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
index de91069713068..b31ca8ccc9886 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
@@ -8,9 +8,6 @@
 
 // REQUIRES: std-at-least-c++23
 
-// These compilers don't support __builtin_is_implicit_lifetime yet.
-// UNSUPPORTED: gcc-15
-
 // <type_traits>
 
 // template<class T> struct is_implicit_lifetime;
@@ -201,7 +198,9 @@ constexpr bool test() {
   test_is_implicit_lifetime<DeletedDestructorViaBaseInNonAggregate, false>();
 
   test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<true>, true>();
+#if !defined(TEST_COMPILER_GCC) || TEST_GCC_VER >= 160200 // This is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126007
   test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<false>, false>();
+#endif
 
   test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<true>, false>();
   test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<false>, true>();
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
index 477667274f6ec..67d9ae5fbbf5c 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
@@ -12,6 +12,9 @@
 
 // T& unique_ptr::operator[](size_t) const
 
+// FIXME: Why does this start failing with GCC 16?
+// XFAIL: gcc-16 && std-at-least-c++20
+
 #include <memory>
 #include <cassert>
 #include <type_traits>
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp
index cdc0ec2bc6fc8..28e420c4c0247 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp
@@ -16,6 +16,9 @@
 
 // See https://llvm.org/PR27684.
 
+// FIXME: Can we avoid instantiating type traits on incomplete types here?
+// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-sfinae-incomplete
+
 #include <tuple>
 #include <cassert>
 
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp
index 85336abdf6420..1a4229356ddbc 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03
 
 // FIXME: Why does this start to fail with GCC 14?
-// XFAIL: !(c++11 || c++14) && gcc-15
+// XFAIL: !(c++11 || c++14) && gcc-16
 
 // See https://llvm.org/PR31384.
 
diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
index 253bd1b85d03e..8e326208696f9 100644
--- a/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
+++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
@@ -81,12 +81,6 @@ TEST_CONSTEXPR_CXX20 bool test() {
     using P = std::pair<int, std::unique_ptr<int> >;
     static_assert(!std::is_copy_assignable<P>::value, "");
   }
-  {
-    using P = std::pair<int, Incomplete&>;
-    static_assert(!std::is_copy_assignable<P>::value, "");
-    P p(42, inc_obj);
-    assert(&p.second == &inc_obj);
-  }
 
   return true;
 }
@@ -99,6 +93,3 @@ int main(int, char**) {
 
   return 0;
 }
-
-struct Incomplete {};
-Incomplete inc_obj;
diff --git a/libcxxabi/test/catch_member_function_pointer_02.pass.cpp b/libcxxabi/test/catch_member_function_pointer_02.pass.cpp
index ec400713620c1..ab6ac2944dfd8 100644
--- a/libcxxabi/test/catch_member_function_pointer_02.pass.cpp
+++ b/libcxxabi/test/catch_member_function_pointer_02.pass.cpp
@@ -12,7 +12,7 @@
 
 // GCC supports noexcept function types but this test still fails.
 // This is likely a bug in their implementation. Investigation needed.
-// XFAIL: gcc-14, gcc-15
+// XFAIL: gcc-16
 
 #include <cassert>
 



More information about the llvm-commits mailing list