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 @@ -212,6 +212,10 @@ CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection ///< in AddressSanitizer +ENUM_CODEGENOPT(SanitizeAddressUseAfterReturn, + llvm::AsanDetectStackUseAfterReturnMode, 2, + llvm::AsanDetectStackUseAfterReturnMode::Runtime + ) ///< Set detection mode for stack-use-after-return. CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1, 0) ///< Enable poisoning operator new[] which is not a replaceable ///< global allocation function in AddressSanitizer 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 @@ -192,6 +192,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 @@ -1587,6 +1587,16 @@ PosFlag, NegFlag, BothFlags<[], " use-after-scope detection in AddressSanitizer">>, Group; +def sanitize_address_use_after_return_EQ + : Joined<["-"], "fsanitize-address-use-after-return=">, + MetaVarName<"">, + Flags<[CC1Option]>, + HelpText<"Select the mode of detecting stack use-after-return in AddressSanitizer">, + Group, + Values<"never,runtime,always">, + NormalizedValuesScope<"llvm::AsanDetectStackUseAfterReturnMode">, + NormalizedValues<["Never", "Runtime", "Always"]>, + MarshallingInfoEnum, "Runtime">; defm sanitize_address_poison_custom_array_cookie : BoolOption<"f", "sanitize-address-poison-custom-array-cookie", CodeGenOpts<"SanitizeAddressPoisonCustomArrayCookie">, DefaultFalse, PosFlag, NegFlag, 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 @@ -12,6 +12,7 @@ #include "clang/Driver/Types.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include #include @@ -58,6 +59,8 @@ bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; bool HwasanUseAliases = false; + llvm::AsanDetectStackUseAfterReturnMode AsanUseAfterReturn = + llvm::AsanDetectStackUseAfterReturnMode::Invalid; public: /// Parses the sanitizer arguments from an argument list. 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 @@ -88,4 +88,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,10 @@ bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtor(); + llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn = + CGOpts.getSanitizeAddressUseAfterReturn(); PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, - UseAfterScope)); + UseAfterScope, UseAfterReturn)); PM.add(createModuleAddressSanitizerLegacyPassPass( /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator, DestructorKind)); @@ -298,7 +301,8 @@ static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createAddressSanitizerFunctionPass( - /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false)); + /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false, + /*UseAfterReturn*/ llvm::AsanDetectStackUseAfterReturnMode::Never)); PM.add(createModuleAddressSanitizerLegacyPassPass( /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true, /*UseOdrIndicator*/ false)); @@ -1144,12 +1148,14 @@ bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; llvm::AsanDtorKind DestructorKind = CodeGenOpts.getSanitizeAddressDtor(); + llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn = + CodeGenOpts.getSanitizeAddressUseAfterReturn(); MPM.addPass(RequireAnalysisPass()); MPM.addPass(ModuleAddressSanitizerPass( CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator, DestructorKind)); - MPM.addPass(createModuleToFunctionPassAdaptor( - AddressSanitizerPass(CompileKernel, Recover, UseAfterScope))); + MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass( + CompileKernel, Recover, UseAfterScope, UseAfterReturn))); } }; 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 @@ -18,6 +18,7 @@ #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include using namespace clang; @@ -841,6 +842,18 @@ AsanDtorKind = parsedAsanDtorKind; } + if (const auto *Arg = Args.getLastArg( + options::OPT_sanitize_address_use_after_return_EQ)) { + auto parsedAsanUseAfterReturn = + AsanDetectStackUseAfterReturnModeFromString(Arg->getValue()); + if (parsedAsanUseAfterReturn == + llvm::AsanDetectStackUseAfterReturnMode::Invalid) { + TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument) + << Arg->getOption().getName() << Arg->getValue(); + } + AsanUseAfterReturn = parsedAsanUseAfterReturn; + } + } else { AsanUseAfterScope = false; // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address. @@ -1112,6 +1125,12 @@ AsanDtorKindToString(AsanDtorKind))); } + if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) { + CmdArgs.push_back(Args.MakeArgString( + "-fsanitize-address-use-after-return=" + + AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn))); + } + if (!HwasanAbi.empty()) { CmdArgs.push_back("-default-function-attr"); CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi)); diff --git a/clang/test/CodeGen/asan-use-after-return.cpp b/clang/test/CodeGen/asan-use-after-return.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/asan-use-after-return.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-RUNTIME \ +// RUN: --implicit-check-not="__asan_stack_malloc_always_" +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \ +// RUN: -fsanitize-address-use-after-return=runtime \ +// RUN: | FileCheck %s --check-prefixes=CHECK-RUNTIME \ +// RUN: --implicit-check-not="__asan_stack_malloc_always_" +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \ +// RUN: -fsanitize-address-use-after-return=always \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ALWAYS \ +// RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return \ +// RUN: --implicit-check-not="__asan_stack_malloc_{{[0-9]}}" +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \ +// RUN: -fsanitize-address-use-after-return=never \ +// RUN: | FileCheck %s \ +// RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return \ +// RUN: --implicit-check-not="__asan_stack_malloc_" + +// CHECK-RUNTIME: load{{.*}}@__asan_option_detect_stack_use_after_return +// CHECK-RUNTIME: call{{.*}}__asan_stack_malloc_0 +// CHECK-ALWAYS: call{{.*}}__asan_stack_malloc_always_0 + +int *function1() { + int x = 0; + +#pragma clang diagnostic ignored "-Wreturn-stack-address" + return &x; +} + +int main() { + auto px = function1(); + return 0; +} diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -452,7 +452,6 @@ // RUN: /FAs \ // RUN: /FAu \ // RUN: /favor:blend \ -// RUN: /fsanitize-address-use-after-return \ // RUN: /fno-sanitize-address-vcasan-lib \ // RUN: /Fifoo \ // RUN: /Fmfoo \ diff --git a/clang/test/Driver/fsanitize-use-after-return.c b/clang/test/Driver/fsanitize-use-after-return.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/fsanitize-use-after-return.c @@ -0,0 +1,30 @@ +// Option should not be passed to the frontend by default. +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address %s \ +// RUN: -### 2>&1 | \ +// RUN: FileCheck %s +// CHECK-NOT: -fsanitize-address-use-after-return + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-use-after-return=never %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-NEVER-ARG %s +// CHECK-NEVER-ARG: "-fsanitize-address-use-after-return=never" + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-use-after-return=runtime %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-RUNTIME %s +// CHECK-RUNTIME: "-fsanitize-address-use-after-return=runtime" + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-use-after-return=always %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-ALWAYS-ARG %s + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-use-after-return=never \ +// RUN: -fsanitize-address-use-after-return=always %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-ALWAYS-ARG %s +// CHECK-ALWAYS-ARG: "-fsanitize-address-use-after-return=always" + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-use-after-return=bad_arg %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-INVALID-ARG %s +// CHECK-INVALID-ARG: error: unsupported argument 'bad_arg' to option 'fsanitize-address-use-after-return=' 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 @@ -99,9 +99,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, + AsanDetectStackUseAfterReturnMode UseAfterReturn = + AsanDetectStackUseAfterReturnMode::Runtime); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); static bool isRequired() { return true; } @@ -109,6 +111,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + AsanDetectStackUseAfterReturnMode UseAfterReturn; }; /// Public interface to the address sanitizer module pass for instrumenting code @@ -135,9 +138,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, + AsanDetectStackUseAfterReturnMode UseAfterReturn = + AsanDetectStackUseAfterReturnMode::Runtime); ModulePass *createModuleAddressSanitizerLegacyPassPass( bool CompileKernel = false, bool Recover = false, bool UseGlobalsGC = true, bool UseOdrIndicator = true, 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 @@ -633,17 +633,24 @@ struct AddressSanitizer { AddressSanitizer(Module &M, const GlobalsMetadata *GlobalsMD, bool CompileKernel = false, bool Recover = false, - bool UseAfterScope = false) + bool UseAfterScope = false, + AsanDetectStackUseAfterReturnMode UseAfterReturn = + AsanDetectStackUseAfterReturnMode::Runtime) : CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan : CompileKernel), Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover), - UseAfterScope(UseAfterScope || ClUseAfterScope), GlobalsMD(*GlobalsMD) { + UseAfterScope(UseAfterScope || ClUseAfterScope), + UseAfterReturn(ClUseAfterReturn.getNumOccurrences() ? ClUseAfterReturn + : UseAfterReturn), + GlobalsMD(*GlobalsMD) { C = &(M.getContext()); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); TargetTriple = Triple(M.getTargetTriple()); Mapping = getShadowMapping(TargetTriple, LongSize, this->CompileKernel); + + assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid); } uint64_t getAllocaSizeInBytes(const AllocaInst &AI) const { @@ -727,6 +734,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + AsanDetectStackUseAfterReturnMode UseAfterReturn; Type *IntptrTy; ShadowMapping Mapping; FunctionCallee AsanHandleNoReturnFunc; @@ -754,11 +762,13 @@ 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, + AsanDetectStackUseAfterReturnMode UseAfterReturn = + AsanDetectStackUseAfterReturnMode::Runtime) : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) { + UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) { initializeAddressSanitizerLegacyPassPass(*PassRegistry::getPassRegistry()); } @@ -777,7 +787,7 @@ const TargetLibraryInfo *TLI = &getAnalysis().getTLI(F); AddressSanitizer ASan(*F.getParent(), &GlobalsMD, CompileKernel, Recover, - UseAfterScope); + UseAfterScope, UseAfterReturn); return ASan.instrumentFunction(F, TLI); } @@ -785,6 +795,7 @@ bool CompileKernel; bool Recover; bool UseAfterScope; + AsanDetectStackUseAfterReturnMode UseAfterReturn; }; class ModuleAddressSanitizer { @@ -1227,10 +1238,11 @@ return GlobalsMetadata(M); } -AddressSanitizerPass::AddressSanitizerPass(bool CompileKernel, bool Recover, - bool UseAfterScope) +AddressSanitizerPass::AddressSanitizerPass( + bool CompileKernel, bool Recover, bool UseAfterScope, + AsanDetectStackUseAfterReturnMode UseAfterReturn) : CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) {} + UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) {} PreservedAnalyses AddressSanitizerPass::run(Function &F, AnalysisManager &AM) { @@ -1238,7 +1250,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, + UseAfterReturn); if (Sanitizer.instrumentFunction(F, TLI)) return PreservedAnalyses::none(); return PreservedAnalyses::all(); @@ -1285,11 +1298,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, + AsanDetectStackUseAfterReturnMode UseAfterReturn) { assert(!CompileKernel || Recover); - return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope); + return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope, + UseAfterReturn); } char ModuleAddressSanitizerLegacyPass::ID = 0; @@ -2953,33 +2967,20 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) { IRBuilder<> IRB(*C); - 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] = + if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always || + ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) { + const char *MallocNameTemplate = + ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always + ? kAsanStackMallocAlwaysNameTemplate + : kAsanStackMallocNameTemplate; + for (int Index = 0; Index <= kMaxAsanStackMallocSizeClass; Index++) { + std::string Suffix = itostr(Index); + AsanStackMallocFunc[Index] = M.getOrInsertFunction( + MallocNameTemplate + Suffix, IntptrTy, IntptrTy); + AsanStackFreeFunc[Index] = 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( @@ -3331,7 +3332,7 @@ LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n"); uint64_t LocalStackSize = L.FrameSize; bool DoStackMalloc = - ClUseAfterReturn != AsanDetectStackUseAfterReturnMode::Never && + ASan.UseAfterReturn != AsanDetectStackUseAfterReturnMode::Never && !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize; bool DoDynamicAlloca = ClDynamicAllocaStack; // Don't do dynamic alloca or stack malloc if: @@ -3354,7 +3355,7 @@ if (DoStackMalloc) { LocalStackBaseAlloca = IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base"); - if (ClUseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) { + if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) { // void *FakeStack = __asan_option_detect_stack_use_after_return // ? __asan_stack_malloc_N(LocalStackSize) // : nullptr; @@ -3377,7 +3378,7 @@ FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term, ConstantInt::get(IntptrTy, 0)); } else { - // assert(ClUseAfterReturn == AsanDetectStackUseAfterReturnMode:Always) + // assert(ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode:Always) // void *FakeStack = __asan_stack_malloc_N(LocalStackSize); // void *LocalStackBase = (FakeStack) ? FakeStack : // alloca(LocalStackSize);