diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h --- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h +++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h @@ -20,5 +20,16 @@ Invalid, ///< Not a valid destructor Kind. // TODO(dliew): Add more more kinds. }; + +/// Mode of ASan detect stack use after return +enum class AsanDetectStackUseAfterReturnMode { + Never, ///< Never detect stack use after return. + Runtime, ///< Detect stack use after return if runtime flag is enabled + ///< (ASAN_OPTIONS=detect_stack_use_after_return=1) + Always, ///< Always detect stack use after return. + Invalid, ///< Not a valid detect mode. +}; + } // namespace llvm + #endif 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 @@ -72,6 +72,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include "llvm/Transforms/Utils/ASanStackFrameLayout.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -257,9 +258,28 @@ "Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64)); -static cl::opt ClUseAfterReturn("asan-use-after-return", - cl::desc("Check stack-use-after-return"), - cl::Hidden, cl::init(true)); +static cl::opt ClUseAfterReturn( + "asan-use-after-return", + cl::desc("Sets the mode of detection for stack-use-after-return."), + cl::values( + clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", + "Never detect stack use after return."), + clEnumValN(AsanDetectStackUseAfterReturnMode::Never, + "0", // only needed to keep unit tests passing + "Redundant with 'never'."), + clEnumValN( + AsanDetectStackUseAfterReturnMode::Runtime, "runtime", + "Detect stack use after return if " + "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), + clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, + "1", // only needed to keep unit tests passing + "redundant with 'runtime'."), + clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", + "Always detect stack use after return."), + clEnumValN(AsanDetectStackUseAfterReturnMode::Always, + "2", // only needed to keep unit tests passing + "Always detect stack use after return.")), + cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime)); static cl::opt ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " @@ -3288,8 +3308,9 @@ auto DescriptionString = ComputeASanStackFrameDescription(SVD); LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n"); uint64_t LocalStackSize = L.FrameSize; - bool DoStackMalloc = ClUseAfterReturn && !ASan.CompileKernel && - LocalStackSize <= kMaxStackMallocSize; + bool DoStackMalloc = + ClUseAfterReturn != AsanDetectStackUseAfterReturnMode::Never && + !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize; bool DoDynamicAlloca = ClDynamicAllocaStack; // Don't do dynamic alloca or stack malloc if: // 1) There is inline asm: too often it makes assumptions on which registers @@ -3311,31 +3332,42 @@ if (DoStackMalloc) { LocalStackBaseAlloca = IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base"); - // void *FakeStack = __asan_option_detect_stack_use_after_return - // ? __asan_stack_malloc_N(LocalStackSize) - // : nullptr; - // void *LocalStackBase = (FakeStack) ? FakeStack : alloca(LocalStackSize); - Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal( - kAsanOptionDetectUseAfterReturn, IRB.getInt32Ty()); - Value *UseAfterReturnIsEnabled = IRB.CreateICmpNE( - IRB.CreateLoad(IRB.getInt32Ty(), OptionDetectUseAfterReturn), - Constant::getNullValue(IRB.getInt32Ty())); - Instruction *Term = - SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false); - IRBuilder<> IRBIf(Term); - StackMallocIdx = StackMallocSizeClass(LocalStackSize); - assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); - Value *FakeStackValue = - IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx], - ConstantInt::get(IntptrTy, LocalStackSize)); - IRB.SetInsertPoint(InsBefore); - FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term, - ConstantInt::get(IntptrTy, 0)); - + if (ClUseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) { + // void *FakeStack = __asan_option_detect_stack_use_after_return + // ? __asan_stack_malloc_N(LocalStackSize) + // : nullptr; + // void *LocalStackBase = (FakeStack) ? FakeStack : + // alloca(LocalStackSize); + Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal( + kAsanOptionDetectUseAfterReturn, IRB.getInt32Ty()); + Value *UseAfterReturnIsEnabled = IRB.CreateICmpNE( + IRB.CreateLoad(IRB.getInt32Ty(), OptionDetectUseAfterReturn), + Constant::getNullValue(IRB.getInt32Ty())); + Instruction *Term = + SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false); + IRBuilder<> IRBIf(Term); + StackMallocIdx = StackMallocSizeClass(LocalStackSize); + assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); + Value *FakeStackValue = + IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx], + ConstantInt::get(IntptrTy, LocalStackSize)); + IRB.SetInsertPoint(InsBefore); + FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term, + ConstantInt::get(IntptrTy, 0)); + } else { + // assert(ClUseAfterReturn == AsanDetectStackUseAfterReturnMode:Always) + // void *FakeStack = __asan_stack_malloc_N(LocalStackSize); + // void *LocalStackBase = (FakeStack) ? FakeStack : + // alloca(LocalStackSize); + StackMallocIdx = StackMallocSizeClass(LocalStackSize); + FakeStack = IRB.CreateCall(AsanStackMallocFunc[StackMallocIdx], + ConstantInt::get(IntptrTy, LocalStackSize)); + } Value *NoFakeStack = IRB.CreateICmpEQ(FakeStack, Constant::getNullValue(IntptrTy)); - Term = SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false); - IRBIf.SetInsertPoint(Term); + Instruction *Term = + SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false); + IRBuilder<> IRBIf(Term); Value *AllocaValue = DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca; 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 @@ -1,8 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -S | FileCheck %s --check-prefixes=CHECK,NEVER ; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -S | FileCheck %s --check-prefixes=CHECK,RUNTIME -; FIXME: Replace 1->2 in D102462. -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -S | FileCheck %s --check-prefixes=CHECK,ALWAYS +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=2 -S | FileCheck %s --check-prefixes=CHECK,ALWAYS target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -104,58 +103,51 @@ ; ALWAYS-LABEL: @Simple( ; ALWAYS-NEXT: entry: ; ALWAYS-NEXT: [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8 -; ALWAYS-NEXT: [[TMP0:%.*]] = load i32, i32* @__asan_option_detect_stack_use_after_return, align 4 -; ALWAYS-NEXT: [[TMP1:%.*]] = icmp ne i32 [[TMP0]], 0 +; ALWAYS-NEXT: [[TMP0:%.*]] = call i64 @__asan_stack_malloc_0(i64 64) +; ALWAYS-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 0 ; ALWAYS-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] ; ALWAYS: 2: -; ALWAYS-NEXT: [[TMP3:%.*]] = call i64 @__asan_stack_malloc_0(i64 64) +; ALWAYS-NEXT: [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32 +; ALWAYS-NEXT: [[TMP3:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64 ; ALWAYS-NEXT: br label [[TMP4]] ; ALWAYS: 4: -; ALWAYS-NEXT: [[TMP5:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[TMP2]] ] -; ALWAYS-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 0 -; ALWAYS-NEXT: br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP9:%.*]] -; ALWAYS: 7: -; ALWAYS-NEXT: [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32 -; ALWAYS-NEXT: [[TMP8:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64 -; ALWAYS-NEXT: br label [[TMP9]] -; ALWAYS: 9: -; ALWAYS-NEXT: [[TMP10:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP8]], [[TMP7]] ] -; ALWAYS-NEXT: store i64 [[TMP10]], i64* [[ASAN_LOCAL_STACK_BASE]], align 8 -; ALWAYS-NEXT: [[TMP11:%.*]] = add i64 [[TMP10]], 32 -; ALWAYS-NEXT: [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to i8* -; ALWAYS-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP10]] to i64* -; ALWAYS-NEXT: store i64 1102416563, i64* [[TMP13]], align 8 -; ALWAYS-NEXT: [[TMP14:%.*]] = add i64 [[TMP10]], 8 -; ALWAYS-NEXT: [[TMP15:%.*]] = inttoptr i64 [[TMP14]] to i64* -; ALWAYS-NEXT: store i64 ptrtoint ([11 x i8]* @___asan_gen_ to i64), i64* [[TMP15]], align 8 -; ALWAYS-NEXT: [[TMP16:%.*]] = add i64 [[TMP10]], 16 -; ALWAYS-NEXT: [[TMP17:%.*]] = inttoptr i64 [[TMP16]] to i64* -; ALWAYS-NEXT: store i64 ptrtoint (void ()* @Simple to i64), i64* [[TMP17]], align 8 -; ALWAYS-NEXT: [[TMP18:%.*]] = lshr i64 [[TMP10]], 3 -; ALWAYS-NEXT: [[TMP19:%.*]] = add i64 [[TMP18]], 2147450880 -; ALWAYS-NEXT: [[TMP20:%.*]] = add i64 [[TMP19]], 0 -; ALWAYS-NEXT: [[TMP21:%.*]] = inttoptr i64 [[TMP20]] to i64* -; ALWAYS-NEXT: store i64 -868083113472691727, i64* [[TMP21]], align 1 -; ALWAYS-NEXT: call void @Foo(i8* [[TMP12]]) -; ALWAYS-NEXT: store i64 1172321806, i64* [[TMP13]], align 8 -; ALWAYS-NEXT: [[TMP22:%.*]] = icmp ne i64 [[TMP5]], 0 -; ALWAYS-NEXT: br i1 [[TMP22]], label [[TMP23:%.*]], label [[TMP30:%.*]] -; ALWAYS: 23: -; ALWAYS-NEXT: [[TMP24:%.*]] = add i64 [[TMP19]], 0 -; ALWAYS-NEXT: [[TMP25:%.*]] = inttoptr i64 [[TMP24]] to i64* -; ALWAYS-NEXT: store i64 -723401728380766731, i64* [[TMP25]], align 1 -; ALWAYS-NEXT: [[TMP26:%.*]] = add i64 [[TMP5]], 56 +; ALWAYS-NEXT: [[TMP5:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP3]], [[TMP2]] ] +; ALWAYS-NEXT: store i64 [[TMP5]], i64* [[ASAN_LOCAL_STACK_BASE]], align 8 +; ALWAYS-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], 32 +; ALWAYS-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to i8* +; ALWAYS-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP5]] to i64* +; ALWAYS-NEXT: store i64 1102416563, i64* [[TMP8]], align 8 +; ALWAYS-NEXT: [[TMP9:%.*]] = add i64 [[TMP5]], 8 +; ALWAYS-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to i64* +; ALWAYS-NEXT: store i64 ptrtoint ([11 x i8]* @___asan_gen_ to i64), i64* [[TMP10]], align 8 +; ALWAYS-NEXT: [[TMP11:%.*]] = add i64 [[TMP5]], 16 +; ALWAYS-NEXT: [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to i64* +; ALWAYS-NEXT: store i64 ptrtoint (void ()* @Simple to i64), i64* [[TMP12]], align 8 +; ALWAYS-NEXT: [[TMP13:%.*]] = lshr i64 [[TMP5]], 3 +; ALWAYS-NEXT: [[TMP14:%.*]] = add i64 [[TMP13]], 2147450880 +; ALWAYS-NEXT: [[TMP15:%.*]] = add i64 [[TMP14]], 0 +; ALWAYS-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to i64* +; ALWAYS-NEXT: store i64 -868083113472691727, i64* [[TMP16]], align 1 +; ALWAYS-NEXT: call void @Foo(i8* [[TMP7]]) +; ALWAYS-NEXT: store i64 1172321806, i64* [[TMP8]], align 8 +; ALWAYS-NEXT: [[TMP17:%.*]] = icmp ne i64 [[TMP0]], 0 +; ALWAYS-NEXT: br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP25:%.*]] +; ALWAYS: 18: +; ALWAYS-NEXT: [[TMP19:%.*]] = add i64 [[TMP14]], 0 +; ALWAYS-NEXT: [[TMP20:%.*]] = inttoptr i64 [[TMP19]] to i64* +; ALWAYS-NEXT: store i64 -723401728380766731, i64* [[TMP20]], align 1 +; ALWAYS-NEXT: [[TMP21:%.*]] = add i64 [[TMP0]], 56 +; ALWAYS-NEXT: [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to i64* +; ALWAYS-NEXT: [[TMP23:%.*]] = load i64, i64* [[TMP22]], align 8 +; ALWAYS-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to i8* +; ALWAYS-NEXT: store i8 0, i8* [[TMP24]], align 1 +; ALWAYS-NEXT: br label [[TMP28:%.*]] +; ALWAYS: 25: +; ALWAYS-NEXT: [[TMP26:%.*]] = add i64 [[TMP14]], 0 ; ALWAYS-NEXT: [[TMP27:%.*]] = inttoptr i64 [[TMP26]] to i64* -; ALWAYS-NEXT: [[TMP28:%.*]] = load i64, i64* [[TMP27]], align 8 -; ALWAYS-NEXT: [[TMP29:%.*]] = inttoptr i64 [[TMP28]] to i8* -; ALWAYS-NEXT: store i8 0, i8* [[TMP29]], align 1 -; ALWAYS-NEXT: br label [[TMP33:%.*]] -; ALWAYS: 30: -; ALWAYS-NEXT: [[TMP31:%.*]] = add i64 [[TMP19]], 0 -; ALWAYS-NEXT: [[TMP32:%.*]] = inttoptr i64 [[TMP31]] to i64* -; ALWAYS-NEXT: store i64 0, i64* [[TMP32]], align 1 -; ALWAYS-NEXT: br label [[TMP33]] -; ALWAYS: 33: +; ALWAYS-NEXT: store i64 0, i64* [[TMP27]], align 1 +; ALWAYS-NEXT: br label [[TMP28]] +; ALWAYS: 28: ; ALWAYS-NEXT: ret void ; entry: diff --git a/llvm/test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll b/llvm/test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll --- a/llvm/test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll @@ -1,12 +1,16 @@ ; Test handling of llvm.lifetime intrinsics in UAR/UAS modes. -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -asan-use-after-scope=0 -S | FileCheck %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -asan-use-after-scope=0 -S | FileCheck %s -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=1 -asan-use-after-scope=0 -S | FileCheck %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -asan-use-after-scope=0 -S | FileCheck %s -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=1 -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=runtime -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=always -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -asan-use-after-scope=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=runtime -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=always -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -asan-use-after-scope=1 -S | FileCheck %s --check-prefix=CHECK-UAS target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/AddressSanitizer/localescape.ll b/llvm/test/Instrumentation/AddressSanitizer/localescape.ll --- a/llvm/test/Instrumentation/AddressSanitizer/localescape.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/localescape.ll @@ -1,7 +1,15 @@ -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return -asan-stack-dynamic-alloca -S | FileCheck %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return -asan-stack-dynamic-alloca -S | FileCheck %s -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -asan-stack-dynamic-alloca=0 -S | FileCheck %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=runtime -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=always -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -asan-stack-dynamic-alloca -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=never -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=runtime -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=always -asan-stack-dynamic-alloca=0 -S | FileCheck %s +; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -asan-stack-dynamic-alloca=0 -S | FileCheck %s target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" target triple = "i686-pc-windows-msvc18.0.0" 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,7 +1,10 @@ -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return -S | FileCheck --check-prefix=CHECK-UAR %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return -S | FileCheck --check-prefix=CHECK-UAR %s -; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -S | FileCheck --check-prefix=CHECK-PLAIN %s -; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -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 %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=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 target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -14,10 +17,10 @@ ; CHECK-PLAIN: ret void ; CHECK-UAR-LABEL: Bar -; CHECK-UAR: load i32, i32* @__asan_option_detect_stack_use_after_return -; CHECK-UAR: label +; 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: label +; CHECK-UAR-RUNTIME: label ; Poison red zones. ; CHECK-UAR: store i64 -1007680412564983311 ; CHECK-UAR: store i64 72057598113936114 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 @@ -1,11 +1,24 @@ ; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca \ -; RUN: -asan-use-after-return -S -enable-new-pm=0 | FileCheck %s +; RUN: -asan-use-after-return=runtime -S -enable-new-pm=0 | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-RUNTIME ; RUN: opt < %s -passes='asan-pipeline' -asan-stack-dynamic-alloca \ -; RUN: -asan-use-after-return -S | FileCheck %s +; RUN: -asan-use-after-return=runtime -S | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-RUNTIME ; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca -asan-mapping-scale=5 \ -; RUN: -asan-use-after-return -S -enable-new-pm=0 | FileCheck %s -; RUN: opt < %s -passes='asan-pipeline' -asan-stack-dynamic-alloca -asan-mapping-scale=5 \ -; RUN: -asan-use-after-return -S | FileCheck %s +; RUN: -asan-use-after-return=runtime -S -enable-new-pm=0 | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-RUNTIME +; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca \ +; RUN: -asan-use-after-return=always -S -enable-new-pm=0 | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-ALWAYS \ +; RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return +; RUN: opt < %s -passes='asan-pipeline' -asan-stack-dynamic-alloca \ +; RUN: -asan-use-after-return=always -S | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-ALWAYS \ +; RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return +; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca -asan-mapping-scale=5 \ +; RUN: -asan-use-after-return=always -S -enable-new-pm=0 | FileCheck %s \ +; RUN: --check-prefixes=CHECK,CHECK-ALWAYS \ +; RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -14,20 +27,23 @@ ; CHECK-LABEL: Func1 ; CHECK: entry: -; CHECK: load i32, i32* @__asan_option_detect_stack_use_after_return +; CHECK-RUNTIME: load i32, i32* @__asan_option_detect_stack_use_after_return +; COM: CHECK-NORUNTIME-NOT: load i32, i32* @__asan_option_detect_stack_use_after_return -; CHECK: [[UAR_ENABLED_BB:^[0-9]+]]: +; CHECK-RUNTIME: [[UAR_ENABLED_BB:^[0-9]+]]: ; CHECK: [[FAKE_STACK_RT:%[0-9]+]] = call i64 @__asan_stack_malloc_ -; CHECK: [[FAKE_STACK_BB:^[0-9]+]]: -; CHECK: [[FAKE_STACK:%[0-9]+]] = phi i64 [ 0, %entry ], [ [[FAKE_STACK_RT]], %[[UAR_ENABLED_BB]] ] -; CHECK: icmp eq i64 [[FAKE_STACK]], 0 +; CHECK-RUNTIME: [[FAKE_STACK_BB:^[0-9]+]]: +; CHECK-RUNTIME: [[FAKE_STACK:%[0-9]+]] = phi i64 [ 0, %entry ], [ [[FAKE_STACK_RT]], %[[UAR_ENABLED_BB]] ] +; CHECK-RUNTIME: icmp eq i64 [[FAKE_STACK]], 0 +; CHECK-ALWAYS: icmp eq i64 [[FAKE_STACK_RT]], 0 ; CHECK: [[NO_FAKE_STACK_BB:^[0-9]+]]: ; CHECK: %MyAlloca = alloca i8, i64 ; CHECK: [[ALLOCA:%[0-9]+]] = ptrtoint i8* %MyAlloca -; CHECK: phi i64 [ [[FAKE_STACK]], %[[FAKE_STACK_BB]] ], [ [[ALLOCA]], %[[NO_FAKE_STACK_BB]] ] +; CHECK-RUNTIME: phi i64 [ [[FAKE_STACK]], %[[FAKE_STACK_BB]] ], [ [[ALLOCA]], %[[NO_FAKE_STACK_BB]] ] +; CHECK-ALWAYS: phi i64 [ [[FAKE_STACK_RT]], %entry ], [ [[ALLOCA]], %[[NO_FAKE_STACK_BB]] ] ; CHECK: ret void