[libcxx-commits] [libcxx] [libc++][hardening] Undeprecate safe mode (PR #68391)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Oct 6 00:23:29 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
<details>
<summary>Changes</summary>
To allow for a smoother transition, keep the safe mode working as is in the LLVM 18 release (the first release that aims to make hardening available), then deprecate it in LLVM 19.
---
Full diff: https://github.com/llvm/llvm-project/pull/68391.diff
6 Files Affected:
- (modified) libcxx/CMakeLists.txt (+9-5)
- (modified) libcxx/docs/BuildingLibcxx.rst (+9)
- (modified) libcxx/docs/ReleaseNotes/18.rst (+17-17)
- (modified) libcxx/docs/UsingLibcxx.rst (+29)
- (modified) libcxx/include/__config (+1-2)
- (modified) libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp (+2-3)
``````````diff
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 68410feb9661816..16540caf68eaf04 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -48,6 +48,10 @@ include(CMakeDependentOption)
include(HandleCompilerRT)
# Basic options ---------------------------------------------------------------
+option(LIBCXX_ENABLE_ASSERTIONS
+ "Enable assertions inside the compiled library, and at the same time make it the
+ default when compiling user code. Note that assertions can be enabled or disabled
+ by users in their own code regardless of this option." OFF)
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
option(LIBCXX_ENABLE_FILESYSTEM
@@ -773,6 +777,11 @@ config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTER
config_define_if_not(LIBCXX_ENABLE_STD_MODULES _LIBCPP_HAS_NO_STD_MODULES)
config_define_if_not(LIBCXX_ENABLE_TIME_ZONE_DATABASE _LIBCPP_HAS_NO_TIME_ZONE_DATABASE)
config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
+
+# TODO(LLVM 19): Produce a deprecation warning.
+if (LIBCXX_ENABLE_ASSERTIONS)
+ set(LIBCXX_HARDENING_MODE "safe")
+endif()
if (LIBCXX_HARDENING_MODE STREQUAL "hardened")
config_define(1 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT)
config_define(0 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT)
@@ -790,11 +799,6 @@ elseif (LIBCXX_HARDENING_MODE STREQUAL "unchecked")
config_define(0 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT)
config_define(0 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT)
endif()
-# TODO(LLVM 19): Remove this after branching for LLVM 18, this is a simple
-# courtesy for vendors to be notified about this change.
-if (LIBCXX_ENABLE_ASSERTIONS)
- message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been replaced by LIBCXX_HARDENING_MODE=safe")
-endif()
if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "serial")
config_define(1 _LIBCPP_PSTL_CPU_BACKEND_SERIAL)
diff --git a/libcxx/docs/BuildingLibcxx.rst b/libcxx/docs/BuildingLibcxx.rst
index e919e1e6f32bfc3..a2041b7e74d8ebb 100644
--- a/libcxx/docs/BuildingLibcxx.rst
+++ b/libcxx/docs/BuildingLibcxx.rst
@@ -215,6 +215,15 @@ libc++ specific options
Toggle the installation of the libc++ headers.
+.. option:: LIBCXX_ENABLE_ASSERTIONS:BOOL
+
+ **Default**: ``OFF``
+
+ Build libc++ with assertions enabled in the compiled library, and enable assertions
+ by default when building user code as well. Assertions can be turned off by users
+ by defining ``_LIBCPP_ENABLE_ASSERTIONS=0``. For details, see
+ :ref:`the documentation <assertions-mode>`.
+
.. option:: LIBCXX_ENABLE_SHARED:BOOL
**Default**: ``ON``
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index 640e6ce0769582c..d639f23eda643c8 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -35,12 +35,6 @@ see the `releases page <https://llvm.org/releases/>`_.
What's New in Libc++ 18.0.0?
==============================
-- The "safe" mode is replaced by the hardened mode in this release. The
- ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable is deprecated and setting it will
- trigger an error; use ``LIBCXX_HARDENING_MODE`` instead. Similarly, the
- ``_LIBCPP_ENABLE_ASSERTIONS`` macro is deprecated and setting it to ``1`` now
- enables the hardened mode. See ``libcxx/docs/Hardening.rst`` for more details.
-
- A new debug mode has been added, replacing the legacy debug mode that was
removed in the LLVM 17 release. See ``libcxx/docs/Hardening.rst`` for more
details.
@@ -63,10 +57,9 @@ Improvements and New Features
enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_HARDENED_MODE=1`` macro. See
:ref:`the hardening documentation <using-hardening-modes>` for more details.
-- The safe mode is now a part of hardening modes. Vendors can configure whether the safe mode is enabled by default
- with the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Users can control whether the safe mode
- is enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_SAFE_MODE=1`` macro. The
- ``_LIBCPP_ENABLE_ASSERTIONS`` macro that was previously used to enable the safe mode is now deprecated. See
+- The safe mode is now also a part of hardening modes. Vendors can configure whether the safe mode is enabled by
+ default with the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Users can control whether the safe
+ mode is enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_SAFE_MODE=1`` macro. See
:ref:`the hardening documentation <using-hardening-modes>` for more details.
- The library now provides a debug mode which is a superset of the safe mode, additionally enabling more expensive
@@ -80,13 +73,6 @@ Improvements and New Features
Deprecations and Removals
-------------------------
-- The "safe" mode is now controlled via the new generalized support for hardening. The ``LIBCXX_ENABLE_ASSERTIONS``
- CMake variable that was used to enable the safe mode is now deprecated and setting it will trigger an error; use the
- ``LIBCXX_HARDENING_MODE`` variable with the value ``safe`` instead. Similarly, the ``_LIBCPP_ENABLE_ASSERTIONS`` macro
- is deprecated (setting it to ``1`` still enables the safe mode in this release while also issuing a deprecation
- warning). ``_LIBCPP_ENABLE_ASSERTIONS`` will be removed entirely in the next release and setting it will become an
- error. See :ref:`the hardening documentation <using-hardening-modes>` for more details.
-
- The non-conforming constructor ``std::future_error(std::error_code)`` has been removed. Please use the
``std::future_error(std::future_errc)`` constructor provided in C++17 instead.
@@ -109,6 +95,13 @@ LLVM 18
LLVM 19
~~~~~~~
+- The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode will be deprecated and setting
+ it will trigger an error; use the ``LIBCXX_HARDENING_MODE`` variable with the value ``safe`` instead. Similarly, the
+ ``_LIBCPP_ENABLE_ASSERTIONS`` macro will be deprecated (setting it to ``1`` still enables the safe mode in this
+ release while also issuing a deprecation warning). ``_LIBCPP_ENABLE_ASSERTIONS`` will be removed entirely in the next
+ release and setting it will become an error. See :ref:`the hardening documentation <using-hardening-modes>` for more
+ details.
+
- The base template for ``std::char_traits`` has been marked as deprecated and will be removed in LLVM 19. If you
are using ``std::char_traits`` with types other than ``char``, ``wchar_t``, ``char8_t``, ``char16_t``, ``char32_t``
or a custom character type for which you specialized ``std::char_traits``, your code will stop working when we
@@ -117,6 +110,13 @@ LLVM 19
Note that the ``_LIBCPP_CHAR_TRAITS_REMOVE_BASE_SPECIALIZATION`` macro can be defined in LLVM 18 to eagerly remove
the specialization and prepare code bases for the unconditional removal in LLVM 19.
+LLVM 20
+~~~~~~~
+
+- The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable and the ``_LIBCPP_ENABLE_ASSERTIONS`` macro that were used to enable
+ the safe mode will be removed.
+
+
ABI Affecting Changes
---------------------
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index ee4cd31a93526e9..e4763bc58a6b989 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -147,6 +147,35 @@ IWYU, you should run the tool like so:
If you would prefer to not use that flag, then you can replace ``/path/to/include-what-you-use/share/libcxx.imp``
file with the libc++-provided ``libcxx.imp`` file.
+.. _assertions-mode:
+
+Enabling the "safe libc++" mode
+===============================
+
+Libc++ contains a number of assertions whose goal is to catch undefined behavior in the
+library, usually caused by precondition violations. Those assertions do not aim to be
+exhaustive -- instead they aim to provide a good balance between safety and performance.
+In particular, these assertions do not change the complexity of algorithms. However, they
+might, in some cases, interfere with compiler optimizations.
+
+By default, these assertions are turned off. Vendors can decide to turn them on while building
+the compiled library by defining ``LIBCXX_ENABLE_ASSERTIONS=ON`` at CMake configuration time.
+When ``LIBCXX_ENABLE_ASSERTIONS`` is used, the compiled library will be built with assertions
+enabled, **and** user code will be built with assertions enabled by default. If
+``LIBCXX_ENABLE_ASSERTIONS=OFF`` at CMake configure time, the compiled library will not contain
+assertions and the default when building user code will be to have assertions disabled.
+As a user, you can consult your vendor to know whether assertions are enabled by default.
+
+Furthermore, independently of any vendor-selected default, users can always control whether
+assertions are enabled in their code by defining ``_LIBCPP_ENABLE_ASSERTIONS=0|1`` before
+including any libc++ header (we recommend passing ``-D_LIBCPP_ENABLE_ASSERTIONS=X`` to the
+compiler). Note that if the compiled library was built by the vendor without assertions,
+functions compiled inside the static or shared library won't have assertions enabled even
+if the user defines ``_LIBCPP_ENABLE_ASSERTIONS=1`` (the same is true for the inverse case
+where the static or shared library was compiled **with** assertions but the user tries to
+disable them). However, most of the code in libc++ is in the headers, so the user-selected
+value for ``_LIBCPP_ENABLE_ASSERTIONS`` (if any) will usually be respected.
+
.. _termination-handler:
Overriding the default termination handler
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 52bf12f80a28b99..a4747424d2c19cd 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -219,11 +219,10 @@
// HARDENING {
-// TODO(hardening): remove this in LLVM 19.
+// TODO(hardening): deprecate this in LLVM 19.
// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes)
// equivalent to setting the safe mode.
# ifdef _LIBCPP_ENABLE_ASSERTIONS
-# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_SAFE_MODE instead."
# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
# endif
diff --git a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
index a4e3d5978155827..61cf26bd2ae142d 100644
--- a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// TODO(hardening): remove in LLVM 19.
+// TODO(hardening): remove in LLVM 20.
// This test ensures that enabling assertions now enables the safe mode.
// Other hardening modes would additionally trigger the error that they are mutually exclusive.
@@ -15,8 +15,7 @@
// UNSUPPORTED: c++03, !has-unix-headers
// The ability to set a custom abort message is required to compare the assertion message.
// XFAIL: availability-verbose_abort-missing
-// Ignore the warning about `_LIBCPP_ENABLE_ASSERTIONS` being deprecated.
-// ADDITIONAL_COMPILE_FLAGS: -Wno-error -D_LIBCPP_ENABLE_ASSERTIONS=1
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
#include <cassert>
#include "check_assertion.h"
``````````
</details>
https://github.com/llvm/llvm-project/pull/68391
More information about the libcxx-commits
mailing list