diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp b/compiler-rt/lib/asan/asan_fake_stack.cpp --- a/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -198,7 +198,13 @@ return GetFakeStack(); } -ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size) { +static FakeStack *GetFakeStackFastAlways() { + if (FakeStack *fs = GetTLSFakeStack()) + return fs; + return GetFakeStack(); +} + +static ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size) { FakeStack *fs = GetFakeStackFast(); if (!fs) return 0; uptr local_stack; @@ -210,7 +216,21 @@ return ptr; } -ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size) { +static ALWAYS_INLINE uptr OnMallocAlways(uptr class_id, uptr size) { + FakeStack *fs = GetFakeStackFastAlways(); + if (!fs) + return 0; + uptr local_stack; + uptr real_stack = reinterpret_cast(&local_stack); + FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack); + if (!ff) + return 0; // Out of fake stack. + uptr ptr = reinterpret_cast(ff); + SetShadow(ptr, size, class_id, 0); + return ptr; +} + +static ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size) { FakeStack::Deallocate(ptr, class_id); SetShadow(ptr, size, class_id, kMagic8); } @@ -228,6 +248,11 @@ uptr ptr, uptr size) { \ OnFree(ptr, class_id, size); \ } +#define DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(class_id) \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr \ + __asan_stack_malloc_always_##class_id(uptr size) { \ + return OnMallocAlways(class_id, size); \ + } DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1) @@ -240,7 +265,23 @@ DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10) + +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(0) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(1) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(2) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(3) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(4) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(5) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(6) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(7) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(8) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(9) +DEFINE_STACK_MALLOC_ALWAYS_WITH_CLASS_ID(10) + extern "C" { +// TODO: remove this method and fix tests that use it by setting +// -asan-use-after-return=never, after modal UAR flag lands +// (https://github.com/google/sanitizers/issues/1394) SANITIZER_INTERFACE_ATTRIBUTE void *__asan_get_current_fake_stack() { return GetFakeStackFast(); } diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc --- a/compiler-rt/lib/asan/asan_interface.inc +++ b/compiler-rt/lib/asan/asan_interface.inc @@ -134,6 +134,17 @@ INTERFACE_FUNCTION(__asan_stack_malloc_8) INTERFACE_FUNCTION(__asan_stack_malloc_9) INTERFACE_FUNCTION(__asan_stack_malloc_10) +INTERFACE_FUNCTION(__asan_stack_malloc_always_0) +INTERFACE_FUNCTION(__asan_stack_malloc_always_1) +INTERFACE_FUNCTION(__asan_stack_malloc_always_2) +INTERFACE_FUNCTION(__asan_stack_malloc_always_3) +INTERFACE_FUNCTION(__asan_stack_malloc_always_4) +INTERFACE_FUNCTION(__asan_stack_malloc_always_5) +INTERFACE_FUNCTION(__asan_stack_malloc_always_6) +INTERFACE_FUNCTION(__asan_stack_malloc_always_7) +INTERFACE_FUNCTION(__asan_stack_malloc_always_8) +INTERFACE_FUNCTION(__asan_stack_malloc_always_9) +INTERFACE_FUNCTION(__asan_stack_malloc_always_10) INTERFACE_FUNCTION(__asan_store1) INTERFACE_FUNCTION(__asan_store2) INTERFACE_FUNCTION(__asan_store4) diff --git a/compiler-rt/test/asan/TestCases/Linux/uar_signals.cpp b/compiler-rt/test/asan/TestCases/Linux/uar_signals.cpp --- a/compiler-rt/test/asan/TestCases/Linux/uar_signals.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/uar_signals.cpp @@ -1,6 +1,8 @@ // This test checks that the implementation of use-after-return // is async-signal-safe. // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread && %run %t +// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -mllvm -asan-use-after-return=never && %run %t +// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -mllvm -asan-use-after-return=always && %run %t // REQUIRES: stable-runtime #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/stack-use-after-return.cpp b/compiler-rt/test/asan/TestCases/Posix/stack-use-after-return.cpp --- a/compiler-rt/test/asan/TestCases/Posix/stack-use-after-return.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/stack-use-after-return.cpp @@ -3,16 +3,32 @@ // RUN: %clangxx_asan -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s // RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t +// RUN: %clangxx_asan -O0 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t -mllvm -asan-use-after-return=never && %run %t // Regression test for a CHECK failure with small stack size and large frame. // RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=131072 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=131072 -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s // -// Test that we can find UAR in a thread other than main: +// Test that we can find UAR in a thread other than main (UAR mode: runtime): // RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s // // Test the max_uar_stack_size_log/min_uar_stack_size_log flag. +// (uses the previous) // // RUN: %env_asan_opts=detect_stack_use_after_return=1:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s // RUN: %env_asan_opts=detect_stack_use_after_return=1:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s +// +// Test that we can find UAR in a thread other than main (UAR mode: always): +// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s +// +// Test the max_uar_stack_size_log/min_uar_stack_size_log flag. +// (uses the previous) +// +// RUN: %env_asan_opts=max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s +// RUN: %env_asan_opts=min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s // This test runs out of stack on AArch64. // UNSUPPORTED: aarch64 @@ -89,7 +105,7 @@ fprintf(stderr, "pthread_attr_setstacksize returned %d\n", ret); abort(); } - + size_t stacksize_check; ret = pthread_attr_getstacksize(&attr, &stacksize_check); if (ret != 0) { @@ -100,7 +116,7 @@ if (stacksize_check != desired_stack_size) { fprintf(stderr, "Unable to set stack size to %d, the stack size is %d.\n", (int)desired_stack_size, (int)stacksize_check); - abort(); + abort(); } } pthread_t t; diff --git a/compiler-rt/test/asan/TestCases/Windows/dll_stack_use_after_return.cpp b/compiler-rt/test/asan/TestCases/Windows/dll_stack_use_after_return.cpp --- a/compiler-rt/test/asan/TestCases/Windows/dll_stack_use_after_return.cpp +++ b/compiler-rt/test/asan/TestCases/Windows/dll_stack_use_after_return.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cl_asan -Od %p/dll_host.cpp -Fe%t // RUN: %clang_cl_asan -LD -Od %s -Fe%t.dll // RUN: %env_asan_opts=detect_stack_use_after_return=1 not %run %t %t.dll 2>&1 | FileCheck %s +// RUN: %clang_cl_asan -LD -Od %s -Fe%t.dll -mllvm -asan-use-after-return=always +// RUN: not %run %t %t.dll 2>&1 | FileCheck %s #include diff --git a/compiler-rt/test/asan/TestCases/Windows/stack_use_after_return.cpp b/compiler-rt/test/asan/TestCases/Windows/stack_use_after_return.cpp --- a/compiler-rt/test/asan/TestCases/Windows/stack_use_after_return.cpp +++ b/compiler-rt/test/asan/TestCases/Windows/stack_use_after_return.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cl_asan -Od %s -Fe%t // RUN: %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clang_cl_asan -Od %s -Fe%t -mllvm -asan-use-after-return=always +// RUN: not %run %t 2>&1 | FileCheck %s char *x; diff --git a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp --- a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp +++ b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp @@ -1,5 +1,7 @@ // RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s // XFAIL: windows-msvc // FIXME: Fix this test under GCC. diff --git a/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cpp b/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cpp --- a/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cpp +++ b/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cpp @@ -4,6 +4,10 @@ // RUN: FileCheck --check-prefix=CHECK-NO-UAR %s // RUN: not %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-UAR %s +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=never && \ +// RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-NO-UAR %s +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always && \ +// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-UAR %s // // On several architectures, the IR does not use byval arguments for foo() and // instead creates a copy in main() and gives foo() a pointer to the copy. In diff --git a/compiler-rt/test/asan/TestCases/scariness_score_test.cpp b/compiler-rt/test/asan/TestCases/scariness_score_test.cpp --- a/compiler-rt/test/asan/TestCases/scariness_score_test.cpp +++ b/compiler-rt/test/asan/TestCases/scariness_score_test.cpp @@ -1,5 +1,6 @@ // Test how we produce the scariness score. +// UAR Mode: runtime // RUN: %clangxx_asan -O0 %s -o %t // On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's // off by default. It's safe for these tests, though, so we turn it on. @@ -33,6 +34,41 @@ // RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25 // RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26 // RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27 +// +// UAR Mode: always +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always +// On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's +// off by default. It's safe for these tests, though, so we turn it on. +// RUN: export %env_asan_opts=handle_abort=1:print_scariness=1:alloc_dealloc_mismatch=1 +// Make sure the stack is limited (may not be the default under GNU make) +// RUN: ulimit -s 4096 +// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: not %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK4 +// RUN: not %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK5 +// RUN: not %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK6 +// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK7 +// RUN: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK8 +// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK9 +// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=CHECK10 +// RUN: not %run %t 11 2>&1 | FileCheck %s --check-prefix=CHECK11 +// RUN: not %run %t 12 2>&1 | FileCheck %s --check-prefix=CHECK12 +// RUN: not %run %t 13 2>&1 | FileCheck %s --check-prefix=CHECK13 +// RUN: not %run %t 14 2>&1 | FileCheck %s --check-prefix=CHECK14 +// RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK15 +// RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK16 +// RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK17 +// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK18 +// RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK19 +// RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK20 +// RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK21 +// RUN: not %run %t 22 2>&1 | FileCheck %s --check-prefix=CHECK22 +// RUN: not %run %t 23 2>&1 | FileCheck %s --check-prefix=CHECK23 +// RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK24 +// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25 +// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26 +// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27 // Parts of the test are too platform-specific: // REQUIRES: x86_64-target-arch // REQUIRES: shell diff --git a/compiler-rt/test/asan/TestCases/uar_and_exceptions.cpp b/compiler-rt/test/asan/TestCases/uar_and_exceptions.cpp --- a/compiler-rt/test/asan/TestCases/uar_and_exceptions.cpp +++ b/compiler-rt/test/asan/TestCases/uar_and_exceptions.cpp @@ -1,6 +1,8 @@ // Test that use-after-return works with exceptions. // RUN: %clangxx_asan -O0 %s -o %t // RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always +// RUN: %run %t #include diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -154,6 +154,8 @@ const char kAsanHandleNoReturnName[] = "__asan_handle_no_return"; static const int kMaxAsanStackMallocSizeClass = 10; const char kAsanStackMallocNameTemplate[] = "__asan_stack_malloc_"; +const char kAsanStackMallocAlwaysNameTemplate[] = + "__asan_stack_malloc_always_"; const char kAsanStackFreeNameTemplate[] = "__asan_stack_free_"; const char kAsanGenPrefix[] = "___asan_gen_"; const char kODRGenPrefix[] = "__odr_asan_gen_"; @@ -2951,13 +2953,33 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) { IRBuilder<> IRB(*C); - for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { - std::string Suffix = itostr(i); - AsanStackMallocFunc[i] = M.getOrInsertFunction( - kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy); - AsanStackFreeFunc[i] = - M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, - IRB.getVoidTy(), IntptrTy, IntptrTy); + switch (ClUseAfterReturn) { + case AsanDetectStackUseAfterReturnMode::Always: + for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { + std::string Suffix = itostr(i); + AsanStackMallocFunc[i] = M.getOrInsertFunction( + kAsanStackMallocAlwaysNameTemplate + Suffix, IntptrTy, IntptrTy); + AsanStackFreeFunc[i] = + M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, + IRB.getVoidTy(), IntptrTy, IntptrTy); + } + break; + case AsanDetectStackUseAfterReturnMode::Runtime: + for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { + std::string Suffix = itostr(i); + AsanStackMallocFunc[i] = M.getOrInsertFunction( + kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy); + AsanStackFreeFunc[i] = + M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, + IRB.getVoidTy(), IntptrTy, IntptrTy); + } + break; + case AsanDetectStackUseAfterReturnMode::Never: + // Do Nothing + break; + case AsanDetectStackUseAfterReturnMode::Invalid: + // Do Nothing + break; } if (ASan.UseAfterScope) { AsanPoisonStackMemoryFunc = M.getOrInsertFunction( diff --git a/llvm/test/Instrumentation/AddressSanitizer/fake-stack.ll b/llvm/test/Instrumentation/AddressSanitizer/fake-stack.ll --- a/llvm/test/Instrumentation/AddressSanitizer/fake-stack.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/fake-stack.ll @@ -103,7 +103,7 @@ ; ALWAYS-LABEL: @Simple( ; ALWAYS-NEXT: entry: ; ALWAYS-NEXT: [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8 -; ALWAYS-NEXT: [[TMP0:%.*]] = call i64 @__asan_stack_malloc_0(i64 64) +; ALWAYS-NEXT: [[TMP0:%.*]] = call i64 @__asan_stack_malloc_always_0(i64 64) ; ALWAYS-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 0 ; ALWAYS-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] ; ALWAYS: 2: diff --git a/llvm/test/Instrumentation/AddressSanitizer/stack-poisoning.ll b/llvm/test/Instrumentation/AddressSanitizer/stack-poisoning.ll --- a/llvm/test/Instrumentation/AddressSanitizer/stack-poisoning.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/stack-poisoning.ll @@ -1,10 +1,10 @@ -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -S | FileCheck --check-prefix=CHECK-PLAIN %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -S | FileCheck --check-prefix=CHECK-PLAIN %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -S | FileCheck --check-prefix=CHECK-PLAIN --implicit-check-not=__asan_stack_malloc %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -S | FileCheck --check-prefix=CHECK-PLAIN --implicit-check-not=__asan_stack_malloc %s ; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=runtime -S | FileCheck --check-prefixes=CHECK-UAR,CHECK-UAR-RUNTIME %s ; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -S | FileCheck --check-prefixes=CHECK-UAR,CHECK-UAR-RUNTIME %s ; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=always -S \ ; RUN: | FileCheck --check-prefixes=CHECK-UAR --implicit-check-not=__asan_option_detect_stack_use_after_return %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -S | FileCheck --check-prefix=CHECK-UAR %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -S | FileCheck --check-prefixes=CHECK-UAR,CHECK-UAR-ALWAYS %s target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -19,7 +19,8 @@ ; CHECK-UAR-LABEL: Bar ; CHECK-UAR-RUNTIME: load i32, i32* @__asan_option_detect_stack_use_after_return ; CHECK-UAR-RUNTIME: label -; CHECK-UAR: call i64 @__asan_stack_malloc_4 +; CHECK-UAR-RUNTIME: call i64 @__asan_stack_malloc_4 +; CHECK-UAR-ALWAYS: call i64 @__asan_stack_malloc_always_4 ; CHECK-UAR-RUNTIME: label ; Poison red zones. ; CHECK-UAR: store i64 -1007680412564983311 diff --git a/llvm/test/Instrumentation/AddressSanitizer/stack_dynamic_alloca.ll b/llvm/test/Instrumentation/AddressSanitizer/stack_dynamic_alloca.ll --- a/llvm/test/Instrumentation/AddressSanitizer/stack_dynamic_alloca.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/stack_dynamic_alloca.ll @@ -31,7 +31,8 @@ ; COM: CHECK-NORUNTIME-NOT: load i32, i32* @__asan_option_detect_stack_use_after_return ; CHECK-RUNTIME: [[UAR_ENABLED_BB:^[0-9]+]]: -; CHECK: [[FAKE_STACK_RT:%[0-9]+]] = call i64 @__asan_stack_malloc_ +; CHECK-RUNTIME: [[FAKE_STACK_RT:%[0-9]+]] = call i64 @__asan_stack_malloc_ +; CHECK-ALWAYS: [[FAKE_STACK_RT:%[0-9]+]] = call i64 @__asan_stack_malloc_always_ ; CHECK-RUNTIME: [[FAKE_STACK_BB:^[0-9]+]]: ; CHECK-RUNTIME: [[FAKE_STACK:%[0-9]+]] = phi i64 [ 0, %entry ], [ [[FAKE_STACK_RT]], %[[UAR_ENABLED_BB]] ]