|
38 | 38 | # define _LIBCPP_FREESTANDING |
39 | 39 | # endif |
40 | 40 |
|
| 41 | +// NOLINTNEXTLINE(libcpp-cpp-version-check) |
| 42 | +# if __cplusplus < 201103L |
| 43 | +# define _LIBCPP_CXX03_LANG |
| 44 | +# endif |
| 45 | + |
| 46 | +# if __has_feature(experimental_library) |
| 47 | +# ifndef _LIBCPP_ENABLE_EXPERIMENTAL |
| 48 | +# define _LIBCPP_ENABLE_EXPERIMENTAL |
| 49 | +# endif |
| 50 | +# endif |
| 51 | + |
| 52 | +// Incomplete features get their own specific disabling flags. This makes it |
| 53 | +// easier to grep for target specific flags once the feature is complete. |
| 54 | +# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) |
| 55 | +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 |
| 56 | +# else |
| 57 | +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 |
| 58 | +# endif |
| 59 | + |
| 60 | +# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
| 61 | +# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
| 62 | +# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
| 63 | +# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
| 64 | + |
41 | 65 | // HARDENING { |
42 | 66 |
|
43 | 67 | // TODO: Remove in LLVM 21. We're making this an error to catch folks who might not have migrated. |
@@ -147,16 +171,53 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \ |
147 | 171 | _LIBCPP_HARDENING_MODE_DEBUG |
148 | 172 | # endif |
149 | 173 |
|
| 174 | +// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts: |
| 175 | +// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts |
| 176 | +// `ignore` semantic which wouldn't evaluate the assertion at all); |
| 177 | +// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution; |
| 178 | +// - `quick-enforce` terminates the program as fast as possible (via trapping); |
| 179 | +// - `enforce` logs an error and then terminates the program. |
| 180 | +// |
| 181 | +// Notes: |
| 182 | +// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant |
| 183 | +// to make adopting hardening easier but should not be used outside of this scenario; |
| 184 | +// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts |
| 185 | +// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for |
| 186 | +// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened" |
| 187 | +// implementation, unlike the other semantics above. |
| 188 | +// clang-format off |
| 189 | +# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1) |
| 190 | +# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2) |
| 191 | +# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3) |
| 192 | +# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4) |
| 193 | +// clang-format on |
| 194 | + |
| 195 | +// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics. |
| 196 | +// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use |
| 197 | +// `enforce` (i.e., log and abort). |
| 198 | +# ifndef _LIBCPP_ASSERTION_SEMANTIC |
| 199 | + |
| 200 | +# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG |
| 201 | +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE |
| 202 | +# else |
| 203 | +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE |
| 204 | +# endif |
| 205 | + |
| 206 | +# else |
| 207 | +# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
| 208 | +# error "Assertion semantics are an experimental feature." |
| 209 | +# endif |
| 210 | +# if defined(_LIBCPP_CXX03_LANG) |
| 211 | +# error "Assertion semantics are not available in the C++03 mode." |
| 212 | +# endif |
| 213 | + |
| 214 | +# endif // _LIBCPP_ASSERTION_SEMANTIC |
| 215 | + |
150 | 216 | // } HARDENING |
151 | 217 |
|
152 | 218 | # define _LIBCPP_TOSTRING2(x) #x |
153 | 219 | # define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) |
154 | 220 |
|
155 | | -// NOLINTNEXTLINE(libcpp-cpp-version-check) |
156 | | -# if __cplusplus < 201103L |
157 | | -# define _LIBCPP_CXX03_LANG |
158 | | -# endif |
159 | | - |
160 | 221 | # ifndef __has_constexpr_builtin |
161 | 222 | # define __has_constexpr_builtin(x) 0 |
162 | 223 | # endif |
@@ -190,25 +251,6 @@ _LIBCPP_HARDENING_MODE_DEBUG |
190 | 251 | # define _LIBCPP_ABI_VCRUNTIME |
191 | 252 | # endif |
192 | 253 |
|
193 | | -# if __has_feature(experimental_library) |
194 | | -# ifndef _LIBCPP_ENABLE_EXPERIMENTAL |
195 | | -# define _LIBCPP_ENABLE_EXPERIMENTAL |
196 | | -# endif |
197 | | -# endif |
198 | | - |
199 | | -// Incomplete features get their own specific disabling flags. This makes it |
200 | | -// easier to grep for target specific flags once the feature is complete. |
201 | | -# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) |
202 | | -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 |
203 | | -# else |
204 | | -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 |
205 | | -# endif |
206 | | - |
207 | | -# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
208 | | -# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
209 | | -# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
210 | | -# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY |
211 | | - |
212 | 254 | # if defined(__MVS__) |
213 | 255 | # include <features.h> // for __NATIVE_ASCII_F |
214 | 256 | # endif |
|
0 commit comments