2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 // TODO: Figure out why this fails with Memory Sanitizer.
13 // This test fails on older llvm, when built with picolibc.
14 // XFAIL: clang-16 && LIBCXX-PICOLIBC-FIXME
21 #define EXPECTED_NUM_FRAMES 50
22 #define NUM_FRAMES_UPPER_BOUND 100
24 __attribute__((noinline
)) _Unwind_Reason_Code
callback(_Unwind_Context
*context
,
29 if (*i
> NUM_FRAMES_UPPER_BOUND
) {
32 return _URC_NO_REASON
;
35 __attribute__((noinline
)) void test_backtrace() {
37 _Unwind_Backtrace(&callback
, &n
);
38 if (n
< EXPECTED_NUM_FRAMES
) {
43 // These functions are effectively the same, but we have to be careful to avoid
44 // unwanted optimizations that would mess with the number of frames we expect.
45 // Surprisingly, slapping `noinline` is not sufficient -- we also have to avoid
46 // writing the function in a way that the compiler can easily spot tail
48 __attribute__((noinline
)) int test1(int i
);
49 __attribute__((noinline
)) int test2(int i
);
51 __attribute__((noinline
)) int test1(int i
) {
56 return i
+ test2(i
- 1);
60 __attribute__((noinline
)) int test2(int i
) {
65 return i
+ test1(i
- 1);
69 int main(int, char**) {
70 int total
= test1(50);
71 assert(total
== 1275);