Skip to content

Commit f613fde

Browse files
committed
- Reflect the assertion semantic in the library ABI tag (with a test);
- Address other feedback.
1 parent 9b0daf4 commit f613fde

File tree

8 files changed

+96
-9
lines changed

8 files changed

+96
-9
lines changed

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/__configuration/hardening.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ _LIBCPP_HARDENING_MODE_DEBUG
152152
//
153153
// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in
154154
// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to
155-
// `enforce`.
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.
156157
//
157158
// Notes:
158159
// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
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+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
13+
14+
// Test that we encode the assertion semantic in an ABI tag to avoid ODR violations when linking TUs that have different
15+
// values for it.
16+
17+
// Note that GCC doesn't support `-Wno-macro-redefined`.
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

libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic
1515
// REQUIRES: verify-support
1616

17-
// Note that GCC doesn't support `-Wno-macro-redefined`.
1817
// 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
1921
// Make sure that common cases of misuse produce readable errors. We deliberately disallow setting the assertion
2022
// semantic as if it were a boolean flag.
2123
// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=0

libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// This test ensures that we can override the assertion semantic used by any checked hardening mode with `enforce` (this
10-
// is valid for the `debug` mode as well, though a no-op).
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).
1111

1212
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
1313
// REQUIRES: has-unix-headers

libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// This test ensures that we can override the assertion semantic used by any hardening mode with `ignore` (this is valid
10-
// for the `none` mode as well, though a no-op).
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).
1111

1212
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
1313
// REQUIRES: has-unix-headers

libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// This test ensures that we can override the assertion semantic used by any checked hardening mode with `observe`.
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.
1011

1112
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
1213
// REQUIRES: has-unix-headers

libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
// This test ensures that we can override the assertion semantic used by any checked hardening mode with `quick-enforce`
10-
// (this is valid for the `fast` and `extensive` modes as well, though a no-op).
10+
// on a per-TU basis (this is valid for the `fast` and `extensive` modes as well, though a no-op).
1111

1212
// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
1313
// REQUIRES: has-unix-headers

0 commit comments

Comments
 (0)