1313
1414#include " clang/Basic/Stack.h"
1515#include " llvm/Support/CrashRecoveryContext.h"
16- #include " llvm/Support/ProgramStack.h"
1716
18- static LLVM_THREAD_LOCAL uintptr_t BottomOfStack = 0 ;
17+ #ifdef _MSC_VER
18+ #include < intrin.h> // for _AddressOfReturnAddress
19+ #endif
1920
20- void clang::noteBottomOfStack (bool ForceSet) {
21- if (!BottomOfStack || ForceSet)
22- BottomOfStack = llvm::getStackPointer ();
21+ static LLVM_THREAD_LOCAL void *BottomOfStack = nullptr ;
22+
23+ static void *getStackPointer () {
24+ #if __GNUC__ || __has_builtin(__builtin_frame_address)
25+ return __builtin_frame_address (0 );
26+ #elif defined(_MSC_VER)
27+ return _AddressOfReturnAddress ();
28+ #else
29+ char CharOnStack = 0 ;
30+ // The volatile store here is intended to escape the local variable, to
31+ // prevent the compiler from optimizing CharOnStack into anything other
32+ // than a char on the stack.
33+ //
34+ // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19.
35+ char *volatile Ptr = &CharOnStack;
36+ return Ptr;
37+ #endif
38+ }
39+
40+ void clang::noteBottomOfStack () {
41+ if (!BottomOfStack)
42+ BottomOfStack = getStackPointer ();
2343}
2444
2545bool clang::isStackNearlyExhausted () {
@@ -31,8 +51,7 @@ bool clang::isStackNearlyExhausted() {
3151 if (!BottomOfStack)
3252 return false ;
3353
34- intptr_t StackDiff =
35- (intptr_t )llvm::getStackPointer () - (intptr_t )BottomOfStack;
54+ intptr_t StackDiff = (intptr_t )getStackPointer () - (intptr_t )BottomOfStack;
3655 size_t StackUsage = (size_t )std::abs (StackDiff);
3756
3857 // If the stack pointer has a surprising value, we do not understand this
@@ -47,12 +66,9 @@ bool clang::isStackNearlyExhausted() {
4766void clang::runWithSufficientStackSpaceSlow (llvm::function_ref<void ()> Diag,
4867 llvm::function_ref<void()> Fn) {
4968 llvm::CrashRecoveryContext CRC;
50- // Preserve the BottomOfStack in case RunSafelyOnNewStack uses split stacks.
51- uintptr_t PrevBottom = BottomOfStack;
52- CRC.RunSafelyOnNewStack ([&] {
53- noteBottomOfStack (true );
69+ CRC.RunSafelyOnThread ([&] {
70+ noteBottomOfStack ();
5471 Diag ();
5572 Fn ();
5673 }, DesiredStackSize);
57- BottomOfStack = PrevBottom;
5874}
0 commit comments