Skip to content

Commit c29b29b

Browse files
authored
[libc++][hardening] Allow setting the assertion semantic via CMake. (#167636)
Add a new CMake variable, `LIBCXX_ASSERTION_SEMANTIC`, that largely mirrors `LIBCXX_HARDENING_MODE`, except that it also supports a special value `hardening_dependent` that indicates the semantic will be selected based on the hardening mode in effect: - `fast` and `extensive` map to `quick_enforce`; - `debug` maps to `enforce`.
1 parent b9c769b commit c29b29b

12 files changed

+327
-25
lines changed

libcxx/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES)
6666
message(FATAL_ERROR
6767
"Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.")
6868
endif()
69+
set(LIBCXX_SUPPORTED_ASSERTION_SEMANTICS hardening_dependent ignore observe quick_enforce enforce)
70+
set(LIBCXX_ASSERTION_SEMANTIC "hardening_dependent" CACHE STRING
71+
"Specify the default assertion semantic to use. This semantic will be used
72+
inside the compiled library and will be the default when compiling user code.
73+
Note that users can override this setting in their own code. This does not
74+
affect the ABI. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}.
75+
`hardening_dependent` is a special value that instructs the library to select
76+
the assertion semantic based on the hardening mode in effect.")
77+
78+
if (NOT "${LIBCXX_ASSERTION_SEMANTIC}" IN_LIST LIBCXX_SUPPORTED_ASSERTION_SEMANTICS)
79+
message(FATAL_ERROR
80+
"Unsupported assertion semantic: '${LIBCXX_ASSERTION_SEMANTIC}'. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}.")
81+
endif()
6982
set(LIBCXX_ASSERTION_HANDLER_FILE
7083
"vendor/llvm/default_assertion_handler.in"
7184
CACHE STRING
@@ -763,6 +776,17 @@ elseif (LIBCXX_HARDENING_MODE STREQUAL "extensive")
763776
elseif (LIBCXX_HARDENING_MODE STREQUAL "debug")
764777
config_define(8 _LIBCPP_HARDENING_MODE_DEFAULT)
765778
endif()
779+
if (LIBCXX_ASSERTION_SEMANTIC STREQUAL "hardening_dependent")
780+
config_define(2 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
781+
elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "ignore")
782+
config_define(4 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
783+
elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "observe")
784+
config_define(8 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
785+
elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "quick_enforce")
786+
config_define(16 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
787+
elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "enforce")
788+
config_define(32 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
789+
endif()
766790

767791
if (LIBCXX_PSTL_BACKEND STREQUAL "serial")
768792
config_define(1 _LIBCPP_PSTL_BACKEND_SERIAL)

libcxx/docs/Hardening.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,20 @@ following options to the compiler:
328328
All the :ref:`same notes <notes-for-users>` apply to setting this macro as for
329329
setting ``_LIBCPP_HARDENING_MODE``.
330330

331+
Notes for vendors
332+
-----------------
333+
334+
Similarly to hardening modes, vendors can set the default assertion semantic by
335+
providing ``LIBCXX_ASSERTION_SEMANTIC`` as a configuration option, with the
336+
possible values of ``hardening_dependent``, ``ignore``, ``observe``,
337+
``quick_enforce`` and ``enforce``. The default value is ``hardening_dependent``
338+
which is a special value that instructs the library to select the semantic based
339+
on the hardening mode in effect (the mapping is described in
340+
:ref:`the main section on assertion semantics <assertion-semantics>`).
341+
342+
This option controls both the assertion semantic that the precompiled library is
343+
built with and the default assertion semantic that users will build with.
344+
331345
.. _override-assertion-handler:
332346

333347
Overriding the assertion failure handler
@@ -447,6 +461,13 @@ The first character of an ABI tag encodes the hardening mode:
447461
- ``d`` -- [d]ebug mode;
448462
- ``n`` -- [n]one mode.
449463

464+
The second character of an ABI tag encodes the assertion semantic:
465+
466+
- ``i`` -- [i]gnore semantic;
467+
- ``o`` -- [o]bserve semantic;
468+
- ``q`` -- [q]uick-enforce semantic;
469+
- ``e`` -- [e]nforce semantic.
470+
450471
Hardened containers status
451472
==========================
452473

libcxx/include/__config

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,14 +291,26 @@ typedef __char32_t char32_t;
291291
# define _LIBCPP_HARDENING_SIG n // "none"
292292
# endif
293293

294+
# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
295+
# define _LIBCPP_ASSERTION_SEMANTIC_SIG o
296+
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
297+
# define _LIBCPP_ASSERTION_SEMANTIC_SIG q
298+
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
299+
# define _LIBCPP_ASSERTION_SEMANTIC_SIG e
300+
# else
301+
# define _LIBCPP_ASSERTION_SEMANTIC_SIG i // `ignore`
302+
# endif
303+
294304
# if !_LIBCPP_HAS_EXCEPTIONS
295305
# define _LIBCPP_EXCEPTIONS_SIG n
296306
# else
297307
# define _LIBCPP_EXCEPTIONS_SIG e
298308
# endif
299309

300310
# define _LIBCPP_ODR_SIGNATURE \
301-
_LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION)
311+
_LIBCPP_CONCAT( \
312+
_LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_ASSERTION_SEMANTIC_SIG), _LIBCPP_EXCEPTIONS_SIG), \
313+
_LIBCPP_VERSION)
302314

303315
// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
304316
// on two levels:

libcxx/include/__config_site.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
// Hardening.
4242
#cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@
43+
#cmakedefine _LIBCPP_ASSERTION_SEMANTIC_DEFAULT @_LIBCPP_ASSERTION_SEMANTIC_DEFAULT@
4344

4445
// __USE_MINGW_ANSI_STDIO gets redefined on MinGW
4546
#ifdef __clang__

libcxx/include/__configuration/hardening.h

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,26 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \
135135
_LIBCPP_HARDENING_MODE_DEBUG
136136
#endif
137137

138-
// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
138+
// The library provides the macro `_LIBCPP_ASSERTION_SEMANTIC` for configuring the assertion semantic used by hardening;
139+
// it can be set to one of the following values:
140+
//
141+
// - `_LIBCPP_ASSERTION_SEMANTIC_IGNORE`;
142+
// - `_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`;
143+
// - `_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`;
144+
// - `_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`.
145+
//
146+
// libc++ assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
139147
// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
140148
// `ignore` semantic which wouldn't evaluate the assertion at all);
141149
// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
142150
// - `quick-enforce` terminates the program as fast as possible (via trapping);
143151
// - `enforce` logs an error and then terminates the program.
144152
//
153+
// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in
154+
// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to
155+
// `enforce`. The `hardening-dependent` semantic cannot be selected explicitly, it is only used when no assertion
156+
// semantic is provided by the user _and_ the library's default semantic is configured to be dependent on hardening.
157+
//
145158
// Notes:
146159
// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
147160
// to make adopting hardening easier but should not be used outside of this scenario;
@@ -150,32 +163,53 @@ _LIBCPP_HARDENING_MODE_DEBUG
150163
// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
151164
// implementation, unlike the other semantics above.
152165
// clang-format off
153-
# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
154-
# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
155-
# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3)
156-
# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4)
166+
# define _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT (1 << 1)
167+
# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 2)
168+
# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 3)
169+
# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 4)
170+
# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 5)
157171
// clang-format on
158172

159-
// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics.
160-
// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use
161-
// `enforce` (i.e., log and abort).
162-
#ifndef _LIBCPP_ASSERTION_SEMANTIC
163-
164-
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
165-
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
166-
# else
167-
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
168-
# endif
169-
170-
#else
171-
173+
// If the user attempts to configure the assertion semantic, check that it is allowed in the current environment.
174+
#if defined(_LIBCPP_ASSERTION_SEMANTIC)
172175
# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
173176
# error "Assertion semantics are an experimental feature."
174177
# endif
175178
# if defined(_LIBCPP_CXX03_LANG)
176179
# error "Assertion semantics are not available in the C++03 mode."
177180
# endif
181+
#endif // defined(_LIBCPP_ASSERTION_SEMANTIC)
182+
183+
// User-provided semantic takes top priority -- don't override if set.
184+
#ifndef _LIBCPP_ASSERTION_SEMANTIC
178185

179-
#endif // _LIBCPP_ASSERTION_SEMANTIC
186+
# ifndef _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
187+
# error _LIBCPP_ASSERTION_SEMANTIC_DEFAULT is not defined. This definition should be set at configuration time in \
188+
the `__config_site` header, please make sure your installation of libc++ is not broken.
189+
# endif
190+
191+
# if _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
192+
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
193+
# else
194+
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
195+
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
196+
# else
197+
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
198+
# endif
199+
# endif // _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
200+
201+
#endif // #ifndef _LIBCPP_ASSERTION_SEMANTIC
202+
203+
// Finally, validate the selected semantic (in case the user tries setting it to an incorrect value):
204+
#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_IGNORE && \
205+
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE && \
206+
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE && \
207+
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
208+
# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
209+
_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
210+
_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
211+
_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
212+
_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
213+
#endif
180214

181215
#endif // _LIBCPP___CONFIGURATION_HARDENING_H
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// ABI tags have no effect in MSVC mode.
10+
// XFAIL: msvc
11+
12+
// Assertion semantics are not supported in C++03 mode and currently are experimental.
13+
// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic
14+
15+
// Test that we encode the assertion semantic in an ABI tag to avoid ODR violations when linking TUs that have different
16+
// values for it.
17+
18+
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE -o %t.tu1.o
19+
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE -o %t.tu2.o
20+
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -o %t.tu3.o
21+
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE -o %t.tu4.o
22+
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
23+
// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe
24+
// RUN: %{exec} %t.exe
25+
26+
#include "test_macros.h"
27+
28+
// `ignore` assertion semantic.
29+
#ifdef TU1
30+
# include <__config>
31+
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; }
32+
int tu1() { return f(); }
33+
#endif // TU1
34+
35+
// `observe` assertion semantic.
36+
#ifdef TU2
37+
# include <__config>
38+
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; }
39+
int tu2() { return f(); }
40+
#endif // TU2
41+
42+
// `quick-enforce` assertion semantic.
43+
#ifdef TU3
44+
# include <__config>
45+
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 3; }
46+
int tu3() { return f(); }
47+
#endif // TU3
48+
49+
// `enforce` assertion semantic.
50+
#ifdef TU4
51+
# include <__config>
52+
_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 4; }
53+
int tu4() { return f(); }
54+
#endif // TU4
55+
56+
#ifdef MAIN
57+
# include <cassert>
58+
59+
int tu1();
60+
int tu2();
61+
int tu3();
62+
int tu4();
63+
64+
int main(int, char**) {
65+
assert(tu1() == 1);
66+
assert(tu2() == 2);
67+
assert(tu3() == 3);
68+
assert(tu4() == 4);
69+
return 0;
70+
}
71+
#endif // MAIN
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This test verifies that setting the assertion semantic to a value that's not part of the predefined constants
10+
// triggers a compile-time error.
11+
12+
// Modules build produces a different error ("Could not build module 'std'").
13+
// UNSUPPORTED: clang-modules-build
14+
// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic
15+
// REQUIRES: verify-support
16+
17+
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=42
18+
// `hardening-dependent` cannot be set as the semantic (it's only an indicator to use hardening-related logic to pick
19+
// the final semantic).
20+
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
21+
// Make sure that common cases of misuse produce readable errors. We deliberately disallow setting the assertion
22+
// semantic as if it were a boolean flag.
23+
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=0
24+
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=1
25+
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC
26+
27+
#include <cassert>
28+
29+
// expected-error@*:* {{_LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: _LIBCPP_ASSERTION_SEMANTIC_IGNORE, _LIBCPP_ASSERTION_SEMANTIC_OBSERVE, _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, _LIBCPP_ASSERTION_SEMANTIC_ENFORCE}}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This test ensures that we can override the assertion semantic used by any checked hardening mode with `enforce` on
10+
// a per-TU basis (this is valid for the `debug` mode as well, though a no-op).
11+
12+
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
13+
// REQUIRES: has-unix-headers
14+
// UNSUPPORTED: c++03, no-localization
15+
// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic
16+
// The ability to set a custom abort message is required to compare the assertion message.
17+
// XFAIL: availability-verbose_abort-missing
18+
// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
19+
20+
#include <cassert>
21+
#include "check_assertion.h"
22+
23+
int main(int, char**) {
24+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
25+
TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire and log a message"); }(),
26+
"Should fire and log a message");
27+
28+
return 0;
29+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This test ensures that we can override the assertion semantic used by any hardening mode with `ignore` on a per-TU
10+
// basis (this is valid for the `none` mode as well, though a no-op).
11+
12+
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
13+
// REQUIRES: has-unix-headers
14+
// UNSUPPORTED: c++03, no-localization
15+
// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic
16+
// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE
17+
18+
#include <cassert>
19+
#include "check_assertion.h"
20+
21+
int main(int, char**) {
22+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
23+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
24+
25+
return 0;
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This test ensures that we can override the assertion semantic used by any checked hardening mode with `observe` on
10+
// a per-TU basis.
11+
12+
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
13+
// REQUIRES: has-unix-headers
14+
// UNSUPPORTED: c++03, no-localization
15+
// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic
16+
// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE
17+
18+
#include <cassert>
19+
#include "check_assertion.h"
20+
21+
int main(int, char**) {
22+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
23+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
24+
// TODO(hardening): check that a message is logged.
25+
26+
return 0;
27+
}

0 commit comments

Comments
 (0)