/ test / test_exception_address_alignment.pass.cpp
test_exception_address_alignment.pass.cpp
 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  // UNSUPPORTED: no-exceptions
10  // UNSUPPORTED: c++03
11  
12  // The <unwind.h> header provided in the SDK of older Xcodes used to provide
13  // an incorrectly aligned _Unwind_Exception type on non-ARM. That causes these
14  // tests to fail when compiling against such a SDK, or when running against a
15  // system libc++abi that was compiled with an incorrect definition of _Unwind_Exception.
16  // XFAIL: apple-clang-12.0.0 && !target={{arm.*}}
17  // XFAIL: apple-clang-11 && !target={{arm.*}}
18  // XFAIL: apple-clang-10 && !target={{arm.*}}
19  // XFAIL: apple-clang-9 && !target={{arm.*}}
20  // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12}}
21  
22  // Test that the address of the exception object is properly aligned as required
23  // by the relevant ABI
24  
25  #include <cstdint>
26  #include <cassert>
27  #include <__cxxabi_config.h>
28  
29  #include <unwind.h>
30  
31  struct __attribute__((aligned)) AlignedType {};
32  
33  // EHABI  : 8-byte aligned
34  // Itanium: Largest supported alignment for the system
35  #if defined(_LIBCXXABI_ARM_EHABI)
36  #  define EXPECTED_ALIGNMENT 8
37  #else
38  #  define EXPECTED_ALIGNMENT alignof(AlignedType)
39  #endif
40  
41  static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT,
42    "_Unwind_Exception is incorrectly aligned. This test is expected to fail");
43  
44  struct MinAligned {  };
45  static_assert(alignof(MinAligned) == 1 && sizeof(MinAligned) == 1, "");
46  
47  int main(int, char**) {
48    for (int i=0; i < 10; ++i) {
49      try {
50        throw MinAligned{};
51      } catch (MinAligned const& ref) {
52        assert(reinterpret_cast<uintptr_t>(&ref) % EXPECTED_ALIGNMENT == 0);
53      }
54    }
55  
56    return 0;
57  }