@@ -39,6 +39,8 @@ modes are:
39
39
40
40
Enabling hardening has no impact on the ABI.
41
41
42
+ .. _notes-for-users :
43
+
42
44
Notes for users
43
45
---------------
44
46
@@ -72,6 +74,10 @@ to control the level by passing **one** of the following options to the compiler
72
74
pre-built components. Most libc++ code is header-based, so a user-provided
73
75
value for ``_LIBCPP_HARDENING_MODE `` will be mostly respected.
74
76
77
+ In some cases, users might want to override the default assertion semantic.
78
+ This can be done similarly to setting the hardening mode; please refer to the
79
+ :ref: `relevant section <assertion-semantics >`.
80
+
75
81
Notes for vendors
76
82
-----------------
77
83
@@ -260,6 +266,60 @@ output. This is less secure and increases the size of the binary (among other
260
266
things, it has to store the error message strings) but makes the failure easier
261
267
to debug. It also allows testing the error messages in our test suite.
262
268
269
+ This default behavior can be customized by users via :ref: `assertion semantics
270
+ <assertion-semantics>`; it can also be completely overridden by vendors by
271
+ providing a :ref: `custom assertion failure handler
272
+ <override-assertion-handler>`.
273
+
274
+ .. _assertion-semantics :
275
+
276
+ Assertion semantics
277
+ -------------------
278
+
279
+ What happens when an assertion fails depends on the assertion semantic being
280
+ used. Four assertion semantics are available, based on C++26 Contracts
281
+ evaluation semantics:
282
+
283
+ - ``ignore `` evaluates the assertion but has no effect if it fails (note that it
284
+ differs from the Contracts ``ignore `` semantic which would not evaluate
285
+ the assertion at all);
286
+ - ``observe `` logs an error (indicating, if possible on the platform, that the
287
+ error is fatal) but continues execution;
288
+ - ``quick-enforce `` terminates the program as fast as possible via a trap
289
+ instruction. It is the default semantic for the production modes (``fast `` and
290
+ ``extensive ``);
291
+ - ``enforce `` logs an error and then terminates the program. It is the default
292
+ semantic for the ``debug `` mode.
293
+
294
+ Notes:
295
+
296
+ - Continuing execution after a hardening check fails results in undefined
297
+ behavior; the ``observe `` semantic is meant to make adopting hardening easier
298
+ but should not be used outside of the adoption period;
299
+ - C++26 wording for Library Hardening precludes a conforming Hardened
300
+ implementation from using the Contracts ``ignore `` semantic when evaluating
301
+ hardened preconditions in the Library. Libc++ allows using this semantic for
302
+ hardened preconditions, but please be aware that using ``ignore `` does not
303
+ produce a conforming "Hardened" implementation, unlike the other semantics
304
+ above.
305
+
306
+ The default assertion semantics are as follows:
307
+
308
+ - ``fast ``: ``quick-enforce ``;
309
+ - ``extensive ``: ``quick-enforce ``;
310
+ - ``debug ``: ``enforce ``.
311
+
312
+ The default assertion semantics can be overridden by passing **one ** of the
313
+ following options to the compiler:
314
+
315
+ - ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE ``
316
+ - ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE ``
317
+ - ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE ``
318
+ - ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE ``
319
+
320
+ All the :ref: `same notes <notes-for-users >` apply to setting this macro as for
321
+ setting ``_LIBCPP_HARDENING_MODE ``.
322
+
263
323
.. _override-assertion-handler :
264
324
265
325
Overriding the assertion failure handler
0 commit comments