diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -14,7 +14,8 @@ * Out-of-bounds accesses to heap, stack and globals * Use-after-free -* Use-after-return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`) +* Use-after-return (clang flag `-fsanitize-address-detect-stack-use-after-return=(always|runtime|never)` default: runtime) + * Add runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1` to enable when compiled with `-fsanitize-address-detect-stack-use-after-return=runtime`) * Use-after-scope (clang flag `-fsanitize-address-use-after-scope`) * Double-free, invalid free * Memory leaks (experimental) diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -881,6 +881,15 @@ * ``global`` - Emit module destructors that are called via a platform specific array (see `llvm.global_dtors`). * ``none`` - Do not emit module destructors. +.. option:: -fsanitize-address-detect-stack-use-after-return= + +Select the enabling method of detect-stack-use-after-return in AddressSanitizer. + +Valid options are: +* ``always`` - Always detect use-after-return. (Code generated and always enabled.) +* ``runtime`` - Detect use-after-return at runtime if enabled by runtime command line (flag `ASAN_OPTIONS=detect_stack_use_after_return=1`) +* ``never`` - Never detect use-after-return. (Code not generated for detection.) + .. option:: -fsanitize-blacklist= Path to blacklist file for sanitizers diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -222,6 +222,10 @@ ENUM_CODEGENOPT(SanitizeAddressDtorKind, llvm::AsanDtorKind, 2, llvm::AsanDtorKind::Global) ///< Set how ASan global ///< destructors are emitted. +ENUM_CODEGENOPT(SanitizeAddressDetectStackUseAfterReturnMode, + llvm::AsanDetectStackUseAfterReturnMode, 2 /* ??? */, + llvm::AsanDetectStackUseAfterReturnMode::Runtime + ) ///< Set detection mode for stack-use-after-return. CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection ///< in MemorySanitizer CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI. diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -198,6 +198,12 @@ llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind); +StringRef AsanDetectStackUseAfterReturnModeToString( + llvm::AsanDetectStackUseAfterReturnMode mode); + +llvm::AsanDetectStackUseAfterReturnMode +AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr); + } // namespace clang #endif // LLVM_CLANG_BASIC_SANITIZERS_H diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1534,6 +1534,16 @@ NormalizedValuesScope<"llvm::AsanDtorKind">, NormalizedValues<["None", "Global"]>, MarshallingInfoEnum, "Global">; +def sanitize_address_detect_stack_use_after_return_EQ + : Joined<["-"], "fsanitize-address-detect-stack-use-after-return=">, + MetaVarName<"">, + Flags<[CC1Option]>, + HelpText<"Select the enabling method of detect-stack-use-after-return in AddressSanitizer">, + Group, + Values<"always,runtime,never">, + NormalizedValuesScope<"llvm::AsanDetectStackUseAfterReturnMode">, + NormalizedValues<["Always", "Runtime", "Never"]>, + MarshallingInfoEnum, "Runtime">; // Note: This flag was introduced when it was necessary to distinguish between // ABI for correct codegen. This is no longer needed, but the flag is // not removed since targeting either ABI will behave the same. diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -44,6 +44,8 @@ bool AsanInvalidPointerCmp = false; bool AsanInvalidPointerSub = false; llvm::AsanDtorKind AsanDtorKind = llvm::AsanDtorKind::Invalid; + llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnMode = + llvm::AsanDetectStackUseAfterReturnMode::Runtime; std::string HwasanAbi; bool LinkRuntimes = true; bool LinkCXXRuntimes = false; diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -80,4 +80,28 @@ .Default(llvm::AsanDtorKind::Invalid); } +StringRef AsanDetectStackUseAfterReturnModeToString( + llvm::AsanDetectStackUseAfterReturnMode mode) { + switch (mode) { + case llvm::AsanDetectStackUseAfterReturnMode::Always: + return "always"; + case llvm::AsanDetectStackUseAfterReturnMode::Runtime: + return "runtime"; + case llvm::AsanDetectStackUseAfterReturnMode::Never: + return "never"; + case llvm::AsanDetectStackUseAfterReturnMode::Invalid: + return "invalid"; + } + return "invalid"; +} + +llvm::AsanDetectStackUseAfterReturnMode +AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr) { + return llvm::StringSwitch(modeStr) + .Case("always", llvm::AsanDetectStackUseAfterReturnMode::Always) + .Case("runtime", llvm::AsanDetectStackUseAfterReturnMode::Runtime) + .Case("never", llvm::AsanDetectStackUseAfterReturnMode::Never) + .Default(llvm::AsanDetectStackUseAfterReturnMode::Invalid); +} + } // namespace clang diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -65,6 +65,7 @@ #include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" @@ -288,8 +289,11 @@ bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtorKind(); + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + CGOpts.getSanitizeAddressDetectStackUseAfterReturnMode(); PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, - UseAfterScope)); + UseAfterScope, + DetectStackUseAfterReturnMode)); PM.add(createModuleAddressSanitizerLegacyPassPass( /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator, DestructorKind)); @@ -298,7 +302,9 @@ static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createAddressSanitizerFunctionPass( - /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false)); + /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false, + /*DetectStackUseAfterReturnMode*/ + llvm::AsanDetectStackUseAfterReturnMode::Never)); PM.add(createModuleAddressSanitizerLegacyPassPass( /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true, /*UseOdrIndicator*/ false)); @@ -1143,12 +1149,15 @@ bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; llvm::AsanDtorKind DestructorKind = CodeGenOpts.getSanitizeAddressDtorKind(); + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + CodeGenOpts.getSanitizeAddressDetectStackUseAfterReturnMode(); MPM.addPass(RequireAnalysisPass()); MPM.addPass(ModuleAddressSanitizerPass( CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator, DestructorKind)); MPM.addPass(createModuleToFunctionPassAdaptor( - AddressSanitizerPass(CompileKernel, Recover, UseAfterScope))); + AddressSanitizerPass(CompileKernel, Recover, UseAfterScope, + DetectStackUseAfterReturnMode))); } }; ASanPass(SanitizerKind::Address, false); diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -841,6 +841,19 @@ AsanDtorKind = parsedAsanDtorKind; } + if (const auto *Arg = Args.getLastArg( + options::OPT_sanitize_address_detect_stack_use_after_return_EQ)) { + auto parsedAsanDetectStackUseAfterReturnMode = + AsanDetectStackUseAfterReturnModeFromString(Arg->getValue()); + if (parsedAsanDetectStackUseAfterReturnMode == + llvm::AsanDetectStackUseAfterReturnMode::Invalid) { + TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument) + << Arg->getOption().getName() << Arg->getValue(); + } + AsanDetectStackUseAfterReturnMode = + parsedAsanDetectStackUseAfterReturnMode; + } + } else { AsanUseAfterScope = false; // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address. @@ -1102,6 +1115,16 @@ AsanDtorKindToString(AsanDtorKind))); } + // Only pass the option to the frontend if the user requested, + // otherwise the frontend will just use the codegen default. + if (AsanDetectStackUseAfterReturnMode != + llvm::AsanDetectStackUseAfterReturnMode::Runtime) { + CmdArgs.push_back( + Args.MakeArgString("-fsanitize-address-detect-stack-use-after-return=" + + AsanDetectStackUseAfterReturnModeToString( + AsanDetectStackUseAfterReturnMode))); + } + if (!HwasanAbi.empty()) { CmdArgs.push_back("-default-function-attr"); CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi)); 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,6 +3,11 @@ // 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 -fsanitize-address-detect-stack-use-after-return=always -O1 %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 2>&1 | FileCheck %s +// RUN: %clangxx_asan -fsanitize-address-detect-stack-use-after-return=runtime -O1 %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 -fsanitize-address-detect-stack-use-after-return=never -O1 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 %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 // diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h --- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h +++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @@ -18,6 +18,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" +#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" namespace llvm { @@ -99,9 +100,11 @@ /// surrounding requested memory to be checked for invalid accesses. class AddressSanitizerPass : public PassInfoMixin { public: - explicit AddressSanitizerPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = false); + explicit AddressSanitizerPass( + bool CompileKernel = false, bool Recover = false, + bool UseAfterScope = false, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + llvm::AsanDetectStackUseAfterReturnMode::Never); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); static bool isRequired() { return true; } @@ -109,6 +112,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode; }; /// Public interface to the address sanitizer module pass for instrumenting code @@ -135,9 +139,11 @@ }; // Insert AddressSanitizer (address sanity checking) instrumentation -FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = false); +FunctionPass *createAddressSanitizerFunctionPass( + bool CompileKernel = false, bool Recover = false, + bool UseAfterScope = false, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + llvm::AsanDetectStackUseAfterReturnMode::Never); ModulePass *createModuleAddressSanitizerLegacyPassPass( bool CompileKernel = false, bool Recover = false, bool UseGlobalsGC = true, bool UseOdrIndicator = true, 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. }; + +/// Modes of ASan detect stack use after return +enum class AsanDetectStackUseAfterReturnMode { + Always, ///< Always detect stack use after return. + Runtime, ///< Detect stack use after return if runtime flag is enabled + ///< (ASAN_OPTIONS=detect_stack_use_after_return=1) + Never, ///< Never 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 @@ -29,6 +29,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/CodeGen/CodeGenPassBuilder.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" @@ -72,6 +73,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" @@ -597,13 +599,17 @@ /// AddressSanitizer: instrument the code in module to find memory bugs. struct AddressSanitizer { - AddressSanitizer(Module &M, const GlobalsMetadata *GlobalsMD, - bool CompileKernel = false, bool Recover = false, - bool UseAfterScope = false) + AddressSanitizer( + Module &M, const GlobalsMetadata *GlobalsMD, bool CompileKernel = false, + bool Recover = false, bool UseAfterScope = false, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + llvm::AsanDetectStackUseAfterReturnMode::Never) : CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan : CompileKernel), Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover), - UseAfterScope(UseAfterScope || ClUseAfterScope), GlobalsMD(*GlobalsMD) { + UseAfterScope(UseAfterScope || ClUseAfterScope), + DetectStackUseAfterReturnMode(DetectStackUseAfterReturnMode), + GlobalsMD(*GlobalsMD) { C = &(M.getContext()); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); @@ -689,6 +695,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode; Type *IntptrTy; ShadowMapping Mapping; FunctionCallee AsanHandleNoReturnFunc; @@ -713,11 +720,14 @@ public: static char ID; - explicit AddressSanitizerLegacyPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = false) + explicit AddressSanitizerLegacyPass( + bool CompileKernel = false, bool Recover = false, + bool UseAfterScope = false, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode = + llvm::AsanDetectStackUseAfterReturnMode::Never) : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) { + UseAfterScope(UseAfterScope), + DetectStackUseAfterReturnMode(DetectStackUseAfterReturnMode) { initializeAddressSanitizerLegacyPassPass(*PassRegistry::getPassRegistry()); } @@ -736,7 +746,7 @@ const TargetLibraryInfo *TLI = &getAnalysis().getTLI(F); AddressSanitizer ASan(*F.getParent(), &GlobalsMD, CompileKernel, Recover, - UseAfterScope); + UseAfterScope, DetectStackUseAfterReturnMode); return ASan.instrumentFunction(F, TLI); } @@ -744,6 +754,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode; }; class ModuleAddressSanitizer { @@ -1182,10 +1193,12 @@ return GlobalsMetadata(M); } -AddressSanitizerPass::AddressSanitizerPass(bool CompileKernel, bool Recover, - bool UseAfterScope) +AddressSanitizerPass::AddressSanitizerPass( + bool CompileKernel, bool Recover, bool UseAfterScope, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode) : CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) {} + UseAfterScope(UseAfterScope), + DetectStackUseAfterReturnMode(DetectStackUseAfterReturnMode) {} PreservedAnalyses AddressSanitizerPass::run(Function &F, AnalysisManager &AM) { @@ -1193,7 +1206,8 @@ Module &M = *F.getParent(); if (auto *R = MAMProxy.getCachedResult(M)) { const TargetLibraryInfo *TLI = &AM.getResult(F); - AddressSanitizer Sanitizer(M, R, CompileKernel, Recover, UseAfterScope); + AddressSanitizer Sanitizer(M, R, CompileKernel, Recover, UseAfterScope, + DetectStackUseAfterReturnMode); if (Sanitizer.instrumentFunction(F, TLI)) return PreservedAnalyses::none(); return PreservedAnalyses::all(); @@ -1240,11 +1254,12 @@ "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) -FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel, - bool Recover, - bool UseAfterScope) { +FunctionPass *llvm::createAddressSanitizerFunctionPass( + bool CompileKernel, bool Recover, bool UseAfterScope, + llvm::AsanDetectStackUseAfterReturnMode DetectStackUseAfterReturnMode) { assert(!CompileKernel || Recover); - return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope); + return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope, + DetectStackUseAfterReturnMode); } char ModuleAddressSanitizerLegacyPass::ID = 0; @@ -2853,13 +2868,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 (ASan.DetectStackUseAfterReturnMode) { + case llvm::AsanDetectStackUseAfterReturnMode::Always: + // 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 llvm::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 llvm::AsanDetectStackUseAfterReturnMode::Never: + // Do Nothing + break; + case llvm::AsanDetectStackUseAfterReturnMode::Invalid: + // Do Nothing + break; } if (ASan.UseAfterScope) { AsanPoisonStackMemoryFunc = M.getOrInsertFunction( @@ -3221,6 +3256,8 @@ // register-relative calculation of local variable addresses. DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall; DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall; + DoStackMalloc &= ASan.DetectStackUseAfterReturnMode != + llvm::AsanDetectStackUseAfterReturnMode::Never; Value *StaticAlloca = DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false);