diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -757,6 +757,10 @@ SanOpts.set(SanitizerKind::KernelHWAddress, false); if (mask & SanitizerKind::KernelHWAddress) SanOpts.set(SanitizerKind::HWAddress, false); + if (mask & SanitizerKind::LocalBounds) + Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds); + if (mask & SanitizerKind::ArrayBounds) + Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds); // SanitizeCoverage is not handled by SanOpts. if (Attr->hasCoverage()) diff --git a/clang/test/CodeGen/sanitize-coverage.c b/clang/test/CodeGen/sanitize-coverage.c --- a/clang/test/CodeGen/sanitize-coverage.c +++ b/clang/test/CodeGen/sanitize-coverage.c @@ -53,6 +53,7 @@ // ASAN-NOT: call void @__asan_report_store // MSAN-NOT: call void @__msan_warning // BOUNDS-NOT: call void @__ubsan_handle_out_of_bounds + // BOUNDS-NOT: call void @llvm.trap() // TSAN-NOT: call void @__tsan_func_entry // UBSAN-NOT: call void @__ubsan_handle if (n) @@ -72,6 +73,7 @@ // ASAN-NOT: call void @__asan_report_store // MSAN-NOT: call void @__msan_warning // BOUNDS-NOT: call void @__ubsan_handle_out_of_bounds + // BOUNDS-NOT: call void @llvm.trap() // TSAN-NOT: call void @__tsan_func_entry // UBSAN-NOT: call void @__ubsan_handle if (n) diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -219,6 +219,7 @@ kw_nosync, kw_nocf_check, kw_nounwind, + kw_nosanitize_bounds, kw_nosanitize_coverage, kw_null_pointer_is_valid, kw_optforfuzzing, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -677,6 +677,7 @@ ATTR_KIND_NO_SANITIZE_COVERAGE = 76, ATTR_KIND_ELEMENTTYPE = 77, ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION = 78, + ATTR_KIND_NO_SANITIZE_BOUNDS = 79, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -178,6 +178,9 @@ /// No SanitizeCoverage instrumentation. def NoSanitizeCoverage : EnumAttr<"nosanitize_coverage", [FnAttr]>; +/// No SanitizeBounds instrumentation. +def NoSanitizeBounds : EnumAttr<"nosanitize_bounds", [FnAttr]>; + /// Null pointer in address space zero is valid. def NullPointerIsValid : EnumAttr<"null_pointer_is_valid", [FnAttr]>; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1453,6 +1453,8 @@ return Attribute::NoUnwind; case bitc::ATTR_KIND_NO_SANITIZE_COVERAGE: return Attribute::NoSanitizeCoverage; + case bitc::ATTR_KIND_NO_SANITIZE_BOUNDS: + return Attribute::NoSanitizeBounds; case bitc::ATTR_KIND_NULL_POINTER_IS_VALID: return Attribute::NullPointerIsValid; case bitc::ATTR_KIND_OPT_FOR_FUZZING: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -690,6 +690,8 @@ return bitc::ATTR_KIND_NO_UNWIND; case Attribute::NoSanitizeCoverage: return bitc::ATTR_KIND_NO_SANITIZE_COVERAGE; + case Attribute::NoSanitizeBounds: + return bitc::ATTR_KIND_NO_SANITIZE_BOUNDS; case Attribute::NullPointerIsValid: return bitc::ATTR_KIND_NULL_POINTER_IS_VALID; case Attribute::OptForFuzzing: diff --git a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp --- a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp +++ b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp @@ -142,6 +142,9 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI, ScalarEvolution &SE) { + if (F.hasFnAttribute(Attribute::NoSanitizeBounds)) + return false; + const DataLayout &DL = F.getParent()->getDataLayout(); ObjectSizeOpts EvalOpts; EvalOpts.RoundToAlign = true; diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -938,6 +938,7 @@ case Attribute::NonLazyBind: case Attribute::NoRedZone: case Attribute::NoUnwind: + case Attribute::NoSanitizeBounds: case Attribute::NoSanitizeCoverage: case Attribute::NullPointerIsValid: case Attribute::OptForFuzzing: