-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc++] Encode additional ODR-affecting properties in the ABI tag (#…
…69669) As explained in `__config`, we have an ABI tag that we use to ensure that we don't run into ODR issues when mixing different versions of libc++ in multiple TUs. However, the reasoning behind that extends not only to different versions of libc++, but also to different configurations of the same version of libc++. In fact, we've been aware of this for a while but never really bothered to make the change because ODR issues are often thought to be benign. Well, it turns out that I just spent over an hour banging my head against an issue that boils down to our lack of encoding of some ODR properties in the ABI tag, so here's the patch we should have done a long time ago. For now, the ODR properties we encode in the ABI tag are: - library version - exceptions vs no-exceptions - hardening mode Those are all things that we support different values for on a per-TU basis and they definitely affect ODR in a meaningful way. We can add more properties later as we see fit. (cherry picked from commit bc792a284362696c91599f9ab01f74eda4b9108f)
- Loading branch information
Showing
3 changed files
with
161 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// TODO: Investigate | ||
// XFAIL: msvc | ||
|
||
// Test that we encode whether exceptions are supported in an ABI tag to avoid | ||
// ODR violations when linking TUs that have different values for it. | ||
|
||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -fno-exceptions -o %t.tu1.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -fexceptions -o %t.tu2.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o | ||
// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.main.o %{flags} %{link_flags} -o %t.exe | ||
// RUN: %{exec} %t.exe | ||
|
||
// -fno-exceptions | ||
#ifdef TU1 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 1; } | ||
int tu1() { return f(); } | ||
#endif // TU1 | ||
|
||
// -fexceptions | ||
#ifdef TU2 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 2; } | ||
int tu2() { return f(); } | ||
#endif // TU2 | ||
|
||
#ifdef MAIN | ||
# include <cassert> | ||
|
||
int tu1(); | ||
int tu2(); | ||
|
||
int main(int, char**) { | ||
assert(tu1() == 1); | ||
assert(tu2() == 2); | ||
return 0; | ||
} | ||
#endif // MAIN |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// TODO: Remove these UNSUPPORTED lines once we change how hardening is enabled to avoid | ||
// mutually exclusive modes being enabled at the same time. | ||
// UNSUPPORTED: libcpp-has-hardened-mode | ||
// UNSUPPORTED: libcpp-has-debug-mode | ||
// UNSUPPORTED: libcpp-has-assertions | ||
|
||
// TODO: Investigate | ||
// XFAIL: msvc | ||
|
||
// Test that we encode the hardening mode in an ABI tag to avoid ODR violations | ||
// when linking TUs that have different values for it. | ||
|
||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -D_LIBCPP_ENABLE_HARDENED_MODE -o %t.tu1.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -D_LIBCPP_ENABLE_ASSERTIONS -o %t.tu2.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -D_LIBCPP_ENABLE_DEBUG_MODE -o %t.tu3.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -o %t.tu4.o | ||
// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o | ||
// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe | ||
// RUN: %{exec} %t.exe | ||
|
||
// hardened mode | ||
#ifdef TU1 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 1; } | ||
int tu1() { return f(); } | ||
#endif // TU1 | ||
|
||
// safe mode | ||
#ifdef TU2 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 2; } | ||
int tu2() { return f(); } | ||
#endif // TU2 | ||
|
||
// debug mode | ||
#ifdef TU3 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 3; } | ||
int tu3() { return f(); } | ||
#endif // TU3 | ||
|
||
// unchecked mode | ||
#ifdef TU4 | ||
# include <__config> | ||
_LIBCPP_HIDE_FROM_ABI inline int f() { return 4; } | ||
int tu4() { return f(); } | ||
#endif // TU4 | ||
|
||
#ifdef MAIN | ||
# include <cassert> | ||
|
||
int tu1(); | ||
int tu2(); | ||
int tu3(); | ||
int tu4(); | ||
|
||
int main(int, char**) { | ||
assert(tu1() == 1); | ||
assert(tu2() == 2); | ||
assert(tu3() == 3); | ||
assert(tu4() == 4); | ||
return 0; | ||
} | ||
#endif // MAIN |