[libcxx-commits] [libcxx] [llvm] [libcxx][CMake] Rework LLVM_ENABLE_ASSERTIONS interaction w. libcxx hardening (PR #229359)

Mészáros Gergely via libcxx-commits libcxx-commits at lists.llvm.org
Sun Oct 11 23:52:15 PDT 2026


https://github.com/Maetveis updated https://github.com/llvm/llvm-project/pull/229359

>From e441e05c572f78dc76649308a0b08f14db127553 Mon Sep 17 00:00:00 2001
From: "Meszaros, Gergely" <gergely.meszaros at intel.com>
Date: Tue, 6 Oct 2026 09:15:23 +0000
Subject: [PATCH 1/2] [libcxx][CMake] Rework LLVM_ENABLE_ASSERTIONS interaction
 w. libcxx hardening

Libcxx hardening (libcxx/docs/Hardening.md) can be set in 2 ways:
- The default hardening mode is set when compiling libcxx, this is applied
  to the pre-compiled object files of libcxx, and sets the default value
  for the hardening macros used in the headers of libcxx.
- Users of libcxx can override the default in the headers for their
  builds by setting a macro.

When LLVM_ENABLE_ASSERTIONS is set, and we are *using* libcxx, we want
to make use of the hardening it offers in the binaries and tests we
build (of other LLVM components, NOT libcxx).

We also set the default hardening mode of libcxx itself when performing
an assertions build. This is orthogonal to the hardening
of binaries and tests. This enables runtime hardening checks not in
the compiler itself, but in the code that links against libcxx
(e.g. applications compiled using the toolchain we just built).

This PR makes this second aspect independently controllable.
Users can now set `LIBCXX_HARDENING_MODE` without it affecting
the hardening in LLVM binaries and tests.
We now unconditionally attempt to enable hardening in our binaries
and tests.

LLVM_ENABLE_ASSERTIONS still implies LIBCXX_HARDENING_MODE=default if
LIBCXX_HARDENING_MODE is not explicitly set (or set to 'auto').
---
 libcxx/CMakeLists.txt                      | 20 +++++++++++++++++---
 llvm/cmake/modules/HandleLLVMOptions.cmake | 13 +++----------
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index d163f0f579c39..88ba515c11abb 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -70,12 +70,14 @@ option(LIBCXX_ENABLE_FILESYSTEM
    available on the platform. This includes things like most parts of <filesystem> and
    others like <fstream>" ON)
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
-set(LIBCXX_SUPPORTED_HARDENING_MODES none fast extensive debug)
-set(LIBCXX_HARDENING_MODE "none" CACHE STRING
+set(LIBCXX_SUPPORTED_HARDENING_MODES auto none fast extensive debug)
+set(LIBCXX_HARDENING_MODE "auto" CACHE STRING
   "Specify the default hardening mode to use. This mode will be used inside the
    compiled library and will be the default when compiling user code. Note that
    users can override this setting in their own code. This does not affect the
-   ABI. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
+   ABI. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.
+   The default value is 'auto', equivalent to 'extensive' when LLVM_ENABLE_ASSERTIONS is ON,
+   and 'none' otherwise.")
 if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES)
   message(FATAL_ERROR
     "Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
@@ -776,6 +778,18 @@ elseif (RUNTIMES_USE_LIBC STREQUAL "llvm-libc")
   config_define(1 _LIBCPP_LIBC_LLVM_LIBC)
 endif()
 
+if (LIBCXX_HARDENING_MODE STREQUAL "auto")
+  # Set a normal (non-cache) variable when the cache value is 'auto'.
+  # This will shadow the cache value, so later references to LIBCXX_HARDENING_MODE
+  # will see the resolved value instead of 'auto'.
+  # This approach allows changes of LLVM_ENABLE_ASSERTIONS to correctly propagate to the
+  # hardening mode without cleaning the CMake cache, while also allows manual overrides.
+  if (LLVM_ENABLE_ASSERTIONS)
+    set(LIBCXX_HARDENING_MODE "extensive")
+  else()
+    set(LIBCXX_HARDENING_MODE "none")
+  endif()
+endif()
 if (LIBCXX_HARDENING_MODE STREQUAL "none")
   config_define(2 _LIBCPP_HARDENING_MODE_DEFAULT)
 elseif (LIBCXX_HARDENING_MODE STREQUAL "fast")
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 943418f7ec0da..43286f57bafb8 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -135,22 +135,15 @@ if( LLVM_ENABLE_ASSERTIONS )
   endif()
   # Enable assertions in libstdc++.
   add_compile_definitions(_GLIBCXX_ASSERTIONS)
-  # Cautiously enable the extensive hardening mode in libc++.
-  if((DEFINED LIBCXX_HARDENING_MODE) AND
-     (NOT LIBCXX_HARDENING_MODE STREQUAL "extensive"))
-    message(WARNING "LLVM_ENABLE_ASSERTIONS implies LIBCXX_HARDENING_MODE \"extensive\" but is overriden from command line with value \"${LIBCXX_HARDENING_MODE}\".")
-  else()
-    set(LIBCXX_HARDENING_MODE "extensive")
-  endif()
 
-  string(TOUPPER "_LIBCPP_HARDENING_MODE_${LIBCXX_HARDENING_MODE}" LIBCXX_HARDENING_MODE_SPELLING)
+  # Enable libc++ hardening mode used to build binaries and tests if supported.
   CHECK_CXX_SOURCE_COMPILES("
-  #define _LIBCPP_HARDENING_MODE ${LIBCXX_HARDENING_MODE_SPELLING}
+  #define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
   #include <string>
   int main() { return 0; }
   " SUPPORTS_LIBCXX_HARDENING_MODE)
   if(SUPPORTS_LIBCXX_HARDENING_MODE)
-    add_compile_definitions(_LIBCPP_HARDENING_MODE=${LIBCXX_HARDENING_MODE_SPELLING})
+    add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE)
   endif()
 endif()
 

>From c2f8339225f2fa09886ab25ddfa699a38a2f52ad Mon Sep 17 00:00:00 2001
From: "Meszaros, Gergely" <gergely.meszaros at intel.com>
Date: Mon, 12 Oct 2026 06:51:24 +0000
Subject: [PATCH 2/2] Revert changes in libcxx, let LIBCXX_HARDENING_MODE
 override asserts

---
 libcxx/CMakeLists.txt                      | 20 +++-----------------
 llvm/cmake/modules/HandleLLVMOptions.cmake |  9 ++++++++-
 2 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 88ba515c11abb..d163f0f579c39 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -70,14 +70,12 @@ option(LIBCXX_ENABLE_FILESYSTEM
    available on the platform. This includes things like most parts of <filesystem> and
    others like <fstream>" ON)
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
-set(LIBCXX_SUPPORTED_HARDENING_MODES auto none fast extensive debug)
-set(LIBCXX_HARDENING_MODE "auto" CACHE STRING
+set(LIBCXX_SUPPORTED_HARDENING_MODES none fast extensive debug)
+set(LIBCXX_HARDENING_MODE "none" CACHE STRING
   "Specify the default hardening mode to use. This mode will be used inside the
    compiled library and will be the default when compiling user code. Note that
    users can override this setting in their own code. This does not affect the
-   ABI. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.
-   The default value is 'auto', equivalent to 'extensive' when LLVM_ENABLE_ASSERTIONS is ON,
-   and 'none' otherwise.")
+   ABI. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
 if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES)
   message(FATAL_ERROR
     "Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
@@ -778,18 +776,6 @@ elseif (RUNTIMES_USE_LIBC STREQUAL "llvm-libc")
   config_define(1 _LIBCPP_LIBC_LLVM_LIBC)
 endif()
 
-if (LIBCXX_HARDENING_MODE STREQUAL "auto")
-  # Set a normal (non-cache) variable when the cache value is 'auto'.
-  # This will shadow the cache value, so later references to LIBCXX_HARDENING_MODE
-  # will see the resolved value instead of 'auto'.
-  # This approach allows changes of LLVM_ENABLE_ASSERTIONS to correctly propagate to the
-  # hardening mode without cleaning the CMake cache, while also allows manual overrides.
-  if (LLVM_ENABLE_ASSERTIONS)
-    set(LIBCXX_HARDENING_MODE "extensive")
-  else()
-    set(LIBCXX_HARDENING_MODE "none")
-  endif()
-endif()
 if (LIBCXX_HARDENING_MODE STREQUAL "none")
   config_define(2 _LIBCPP_HARDENING_MODE_DEFAULT)
 elseif (LIBCXX_HARDENING_MODE STREQUAL "fast")
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 43286f57bafb8..8d1e8392928f1 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -135,8 +135,15 @@ if( LLVM_ENABLE_ASSERTIONS )
   endif()
   # Enable assertions in libstdc++.
   add_compile_definitions(_GLIBCXX_ASSERTIONS)
+  # Cautiously enable the extensive hardening mode in the build of libc++.
+  if((DEFINED LIBCXX_HARDENING_MODE) AND
+     (NOT LIBCXX_HARDENING_MODE STREQUAL "extensive"))
+    message(STATUS "LLVM_ENABLE_ASSERTIONS implies LIBCXX_HARDENING_MODE \"extensive\" but is overriden from command line with value \"${LIBCXX_HARDENING_MODE}\".")
+  else()
+    set(LIBCXX_HARDENING_MODE "extensive")
+  endif()
 
-  # Enable libc++ hardening mode used to build binaries and tests if supported.
+  # Enable libc++ extensive hardening mode used to build binaries and tests if supported.
   CHECK_CXX_SOURCE_COMPILES("
   #define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
   #include <string>



More information about the libcxx-commits mailing list