brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.9 KiB · 9fd8e5d Raw
74 lines · cpp
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//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-exception7//8//===----------------------------------------------------------------------===//9 10// TODO: Figure out why this fails with Memory Sanitizer.11// XFAIL: msan12 13// This test fails on older llvm, when built with picolibc.14// XFAIL: clang-16 && LIBCXX-PICOLIBC-FIXME15 16#undef NDEBUG17#include <assert.h>18#include <stdlib.h>19#include <unwind.h>20 21#define EXPECTED_NUM_FRAMES 5022#define NUM_FRAMES_UPPER_BOUND 10023 24__attribute__((noinline)) _Unwind_Reason_Code callback(_Unwind_Context *context,25                                                       void *cnt) {26  (void)context;27  int *i = (int *)cnt;28  ++*i;29  if (*i > NUM_FRAMES_UPPER_BOUND) {30    abort();31  }32  return _URC_NO_REASON;33}34 35__attribute__((noinline)) void test_backtrace() {36  int n = 0;37  _Unwind_Backtrace(&callback, &n);38  if (n < EXPECTED_NUM_FRAMES) {39    abort();40  }41}42 43// These functions are effectively the same, but we have to be careful to avoid44// unwanted optimizations that would mess with the number of frames we expect.45// Surprisingly, slapping `noinline` is not sufficient -- we also have to avoid46// writing the function in a way that the compiler can easily spot tail47// recursion.48__attribute__((noinline)) int test1(int i);49__attribute__((noinline)) int test2(int i);50 51__attribute__((noinline)) int test1(int i) {52  if (i == 0) {53    test_backtrace();54    return 0;55  } else {56    return i + test2(i - 1);57  }58}59 60__attribute__((noinline)) int test2(int i) {61  if (i == 0) {62    test_backtrace();63    return 0;64  } else {65    return i + test1(i - 1);66  }67}68 69int main(int, char**) {70  int total = test1(50);71  assert(total == 1275);72  return 0;73}74