Conversation
|
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-compiler-rt-sanitizer Author: PiJoules ChangesThis relands commit bf8cf4b (#190871), which was reverted in commit e3b3706 (#193655). This checks that the range covered by this intrinsic is dereferenceable. Specifically it checks for Fixes included in this reland:
Patch is 22.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224163.diff 16 Files Affected:
diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 900a3fc5c9865..d50c5c13b48c8 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -160,10 +160,10 @@ void *SANITIZER_CDECL __asan_get_report_address(void);
/// Gets access type of an ASan error (useful for calling from the debugger).
///
-/// Returns access type (read or write) if an error has been (or is being)
-/// reported. Otherwise returns 0.
+/// Returns access type (read or write or assumption) if an error has been (or
+/// is being) reported. Otherwise returns 0.
///
-/// \returns Access type (0 = read, 1 = write).
+/// \returns Access type (0 = read, 1 = write, 2 = assumption).
int SANITIZER_CDECL __asan_get_report_access_type(void);
/// Gets access size of an ASan error (useful for calling from the debugger).
diff --git a/compiler-rt/lib/asan/AIX/asan.link_with_main_exec.txt b/compiler-rt/lib/asan/AIX/asan.link_with_main_exec.txt
index 0e02267803fbd..bdd914c75a15c 100644
--- a/compiler-rt/lib/asan/AIX/asan.link_with_main_exec.txt
+++ b/compiler-rt/lib/asan/AIX/asan.link_with_main_exec.txt
@@ -1,5 +1,7 @@
#! .
__asan_report_load_n
+__asan_report_assume_dereferenceable
+__asan_report_assume_dereferenceable_noabort
__asan_loadN
__asan_report_load1
__asan_load1
diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp
index 6b4d25c4aa3f9..cf83fffb1594d 100644
--- a/compiler-rt/lib/asan/asan_errors.cpp
+++ b/compiler-rt/lib/asan/asan_errors.cpp
@@ -440,14 +440,14 @@ static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
}
ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
- bool is_write_, uptr access_size_)
+ AccessType access_type_, uptr access_size_)
: ErrorBase(tid),
addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
pc(pc_),
bp(bp_),
sp(sp_),
access_size(access_size_),
- is_write(is_write_),
+ access_type(access_type_),
shadow_val(0) {
scariness.Clear();
if (access_size) {
@@ -458,7 +458,13 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
} else if (access_size >= 10) {
scariness.Scare(15, "multi-byte");
}
- is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");
+ if (access_type == AccessType::Write) {
+ scariness.Scare(20, "write");
+ } else if (access_type == AccessType::Read) {
+ scariness.Scare(1, "read");
+ } else if (access_type == AccessType::Assumption) {
+ scariness.Scare(1, "assumption");
+ }
// Determine the error type.
bug_descr = "unknown-crash";
@@ -485,7 +491,8 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
case kAsanHeapFreeMagic:
bug_descr = "heap-use-after-free";
bug_type_score = 20;
- if (!is_write) read_after_free_bonus = 18;
+ if (access_type == AccessType::Read)
+ read_after_free_bonus = 18;
break;
case kAsanStackLeftRedzoneMagic:
bug_descr = "stack-buffer-underflow";
@@ -505,7 +512,8 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
case kAsanStackAfterReturnMagic:
bug_descr = "stack-use-after-return";
bug_type_score = 30;
- if (!is_write) read_after_free_bonus = 18;
+ if (access_type == AccessType::Read)
+ read_after_free_bonus = 18;
break;
case kAsanUserPoisonedMemoryMagic:
bug_descr = "use-after-poison";
@@ -672,9 +680,23 @@ void ErrorGeneric::Print() {
bug_descr, (void *)addr, (void *)pc, (void *)bp, (void *)sp);
Printf("%s", d.Default());
- Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),
- access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
- (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());
+ const char* access_type = "ACCESS";
+ if (access_size) {
+ switch (this->access_type) {
+ case AccessType::Assumption:
+ access_type = "ASSUME";
+ break;
+ case AccessType::Read:
+ access_type = "READ";
+ break;
+ case AccessType::Write:
+ access_type = "WRITE";
+ break;
+ }
+ }
+ Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(), access_type,
+ access_size, (void*)addr, AsanThreadIdAndName(tid).c_str(),
+ d.Default());
scariness.Print();
GET_STACK_TRACE_FATAL(pc, bp);
diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h
index d9a626e711282..e4d3d993fad51 100644
--- a/compiler-rt/lib/asan/asan_errors.h
+++ b/compiler-rt/lib/asan/asan_errors.h
@@ -407,16 +407,22 @@ struct ErrorInvalidPointerPair : ErrorBase {
};
struct ErrorGeneric : ErrorBase {
+ enum class AccessType : u8 {
+ Read = 0,
+ Write = 1,
+ Assumption = 2,
+ };
+
AddressDescription addr_description;
uptr pc, bp, sp;
uptr access_size;
const char *bug_descr;
- bool is_write;
+ AccessType access_type;
u8 shadow_val;
ErrorGeneric() = default; // (*)
- ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, bool is_write_,
- uptr access_size_);
+ ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
+ AccessType access_type_, uptr access_size_);
void Print();
};
diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
index f2aaedf293f39..74fca77f52f26 100644
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -98,6 +98,8 @@ INTERFACE_FUNCTION(__asan_report_load8_noabort)
INTERFACE_FUNCTION(__asan_report_load16_noabort)
INTERFACE_FUNCTION(__asan_report_load_n_noabort)
INTERFACE_FUNCTION(__asan_report_present)
+INTERFACE_FUNCTION(__asan_report_assume_dereferenceable)
+INTERFACE_FUNCTION(__asan_report_assume_dereferenceable_noabort)
INTERFACE_FUNCTION(__asan_report_store1)
INTERFACE_FUNCTION(__asan_report_store2)
INTERFACE_FUNCTION(__asan_report_store4)
diff --git a/compiler-rt/lib/asan/asan_report.cpp b/compiler-rt/lib/asan/asan_report.cpp
index df797deaa5dbd..234fd35d54afd 100644
--- a/compiler-rt/lib/asan/asan_report.cpp
+++ b/compiler-rt/lib/asan/asan_report.cpp
@@ -528,11 +528,27 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
(void)exp;
ScopedInErrorReport in_report(fatal);
- ErrorGeneric error(GetCurrentTidOrInvalid(), pc, bp, sp, addr, is_write,
+ ErrorGeneric error(GetCurrentTidOrInvalid(), pc, bp, sp, addr,
+ is_write ? ErrorGeneric::AccessType::Write
+ : ErrorGeneric::AccessType::Read,
access_size);
in_report.ReportError(error);
}
+void ReportAssumeDereferenceableError(uptr pc, uptr bp, uptr sp, uptr addr,
+ uptr dereferenceable_size, bool fatal) {
+ if (!fatal && SuppressErrorReport(pc))
+ return;
+ ENABLE_FRAME_POINTER;
+
+ ScopedInErrorReport in_report(fatal);
+ ErrorGeneric error(GetCurrentTidOrInvalid(), pc, bp, sp, addr,
+ ErrorGeneric::AccessType::Assumption,
+ dereferenceable_size);
+ error.bug_descr = "dereferenceable-assumption-violation";
+ in_report.ReportError(error);
+}
+
} // namespace __asan
// --------------------------- Interface --------------------- {{{1
@@ -590,7 +606,8 @@ uptr __asan_get_report_address() {
int __asan_get_report_access_type() {
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.is_write;
+ return static_cast<int>(
+ ScopedInErrorReport::CurrentError().Generic.access_type);
return 0;
}
diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h
index d67cb04daba68..d1ce7c194d853 100644
--- a/compiler-rt/lib/asan/asan_report.h
+++ b/compiler-rt/lib/asan/asan_report.h
@@ -49,6 +49,8 @@ bool ParseFrameDescription(const char *frame_descr,
// Different kinds of error reports.
void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
uptr access_size, u32 exp, bool fatal);
+void ReportAssumeDereferenceableError(uptr pc, uptr bp, uptr sp, uptr addr,
+ uptr dereferenceable_size, bool fatal);
void ReportDeadlySignal(const SignalContext &sig);
void ReportNewDeleteTypeMismatch(uptr addr, uptr delete_size,
uptr delete_alignment,
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index c036a13a11029..9726f8f447b59 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -156,6 +156,22 @@ void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
ASAN_REPORT_ERROR_N(load, false)
ASAN_REPORT_ERROR_N(store, true)
+extern "C" NOINLINE INTERFACE_ATTRIBUTE void
+__asan_report_assume_dereferenceable(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportAssumeDereferenceableError(pc, bp, sp, addr, size, true);
+ }
+}
+
+extern "C" NOINLINE INTERFACE_ATTRIBUTE void
+__asan_report_assume_dereferenceable_noabort(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportAssumeDereferenceableError(pc, bp, sp, addr, size, false);
+ }
+}
+
#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
uptr sp = MEM_TO_SHADOW(addr); \
uptr s = size <= ASAN_SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
diff --git a/compiler-rt/lib/asan_abi/asan_abi_tbd.txt b/compiler-rt/lib/asan_abi/asan_abi_tbd.txt
index effb9190b2897..5eeeb519a7946 100644
--- a/compiler-rt/lib/asan_abi/asan_abi_tbd.txt
+++ b/compiler-rt/lib/asan_abi/asan_abi_tbd.txt
@@ -25,3 +25,5 @@ __asan_get_report_src_address
__asan_report_error
__asan_report_present
__asan_set_error_report_callback
+__asan_report_assume_dereferenceable
+__asan_report_assume_dereferenceable_noabort
diff --git a/compiler-rt/test/asan/TestCases/assume_dereferenceable.cpp b/compiler-rt/test/asan/TestCases/assume_dereferenceable.cpp
new file mode 100644
index 0000000000000..7970ec4ee7f7f
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/assume_dereferenceable.cpp
@@ -0,0 +1,91 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-assume-dereferenceable=1 -fsanitize-recover=address %s -o %t && %env_asan_opts=halt_on_error=0 %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: msvc
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void test_malloc_fully_oob() {
+ char *p = (char *)malloc(10);
+ fprintf(stderr, "test_malloc_fully_oob\n");
+ // CHECK: test_malloc_fully_oob
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR1:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 20 at [[PTR1]] thread T0
+ __builtin_assume_dereferenceable(p, 20);
+ free(p);
+}
+
+void test_malloc_partial_right() {
+ char *p = (char *)malloc(10);
+ fprintf(stderr, "test_malloc_partial_right\n");
+ // CHECK: test_malloc_partial_right
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR2:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 10 at [[PTR2]] thread T0
+ __builtin_assume_dereferenceable(p + 5, 10);
+ free(p);
+}
+
+void test_malloc_partial_left() {
+ char *p = (char *)malloc(10);
+ fprintf(stderr, "test_malloc_partial_left\n");
+ // CHECK: test_malloc_partial_left
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR3:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 10 at [[PTR3]] thread T0
+ __builtin_assume_dereferenceable(p - 5, 10);
+ free(p);
+}
+
+void test_stack_fully_oob(int i) {
+ char p[10];
+ fprintf(stderr, "test_stack_fully_oob\n");
+ // CHECK: test_stack_fully_oob
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR4:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 100 at [[PTR4]] thread T0
+ __builtin_assume_dereferenceable(p, 100);
+
+ // This is here just to force ASan to emit instrumentation for poisoning
+ // redzones around the stack. By default, ASan will not instrument stack
+ // allocations that it deems "uninteresting".
+ p[i] = 0;
+}
+
+void test_stack_partial_right(int i) {
+ char p[10];
+ fprintf(stderr, "test_stack_partial_right\n");
+ // CHECK: test_stack_partial_right
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR5:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 10 at [[PTR5]] thread T0
+ __builtin_assume_dereferenceable(p + 5, 10);
+ p[i] = 0;
+}
+
+void test_stack_partial_left(int i) {
+ char p[10];
+ fprintf(stderr, "test_stack_partial_left\n");
+ // CHECK: test_stack_partial_left
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR6:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 10 at [[PTR6]] thread T0
+ __builtin_assume_dereferenceable(p - 5, 10);
+ p[i] = 0;
+}
+
+void test_malloc_completely_poisoned() {
+ char *p = (char *)malloc(10);
+ free(p);
+ fprintf(stderr, "test_malloc_completely_poisoned\n");
+ // CHECK: test_malloc_completely_poisoned
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR7:0x[0-9a-fA-F]+]]
+ // CHECK: ASSUME of size 10 at [[PTR7]] thread T0
+ __builtin_assume_dereferenceable(p, 10);
+}
+
+int main() {
+ test_malloc_fully_oob();
+ test_malloc_partial_right();
+ test_malloc_partial_left();
+ test_stack_fully_oob(0);
+ test_stack_partial_right(0);
+ test_stack_partial_left(0);
+ test_malloc_completely_poisoned();
+ return 0;
+}
+
diff --git a/compiler-rt/test/asan/TestCases/assume_dereferenceable_fully_poisoned.cpp b/compiler-rt/test/asan/TestCases/assume_dereferenceable_fully_poisoned.cpp
new file mode 100644
index 0000000000000..ad899d3d3feac
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/assume_dereferenceable_fully_poisoned.cpp
@@ -0,0 +1,13 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-assume-dereferenceable=1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: msvc
+
+#include <stdlib.h>
+
+int main() {
+ char *p = (char *)malloc(10);
+ free(p);
+ // CHECK: AddressSanitizer: dereferenceable-assumption-violation
+ // CHECK: ASSUME of size 10
+ __builtin_assume_dereferenceable(p, 10);
+ return 0;
+}
diff --git a/compiler-rt/test/asan/TestCases/assume_dereferenceable_halt_on_error.cpp b/compiler-rt/test/asan/TestCases/assume_dereferenceable_halt_on_error.cpp
new file mode 100644
index 0000000000000..08770b9adfe13
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/assume_dereferenceable_halt_on_error.cpp
@@ -0,0 +1,23 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-assume-dereferenceable=1 -fsanitize-recover=address %s -o %t
+// RUN: %env_asan_opts=halt_on_error=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=halt_on_error=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
+// UNSUPPORTED: msvc
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ char *p = (char *)malloc(10);
+
+ // CHECK: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR:0x[0-9a-fA-F]+]]
+
+ // CHECK-RECOVER: ERROR: AddressSanitizer: dereferenceable-assumption-violation on address [[PTR:0x[0-9a-fA-F]+]]
+ __builtin_assume_dereferenceable(p, 20);
+ free(p);
+
+ fprintf(stderr, "EXECUTED AFTER ERROR\n");
+ // CHECK-NOT: EXECUTED AFTER ERROR
+ // CHECK-RECOVER: EXECUTED AFTER ERROR
+
+ return 0;
+}
diff --git a/compiler-rt/test/asan/TestCases/assume_dereferenceable_pass.cpp b/compiler-rt/test/asan/TestCases/assume_dereferenceable_pass.cpp
new file mode 100644
index 0000000000000..791abe1bc108d
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/assume_dereferenceable_pass.cpp
@@ -0,0 +1,36 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-assume-dereferenceable=1 %s -o %t && %run %t
+// UNSUPPORTED: msvc
+
+#include <stdlib.h>
+
+void test_pass_1() {
+ char *p = (char *)malloc(20);
+ __builtin_assume_dereferenceable(p, 10);
+ __builtin_assume_dereferenceable(p, 20);
+ free(p);
+}
+
+void test_pass_2() {
+ char *p = (char *)malloc(10);
+ __builtin_assume_dereferenceable(p, 0);
+ free(p);
+}
+
+void test_stack_pass_1() {
+ char p[20];
+ __builtin_assume_dereferenceable(p, 10);
+ __builtin_assume_dereferenceable(p, 20);
+}
+
+void test_stack_pass_2() {
+ char p[10];
+ __builtin_assume_dereferenceable(p, 0);
+}
+
+int main() {
+ test_pass_1();
+ test_pass_2();
+ test_stack_pass_1();
+ test_stack_pass_2();
+ return 0;
+}
diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp
index f6038693873e1..b92f92c07df01 100644
--- a/compiler-rt/test/asan/TestCases/debug_report.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_report.cpp
@@ -45,7 +45,7 @@ __asan_on_error() {
void *bp = __asan_get_report_bp();
void *sp = __asan_get_report_sp();
void *addr = __asan_get_report_address();
- int is_write = __asan_get_report_access_type();
+ int access_type = __asan_get_report_access_type();
size_t access_size = __asan_get_report_access_size();
const char *description = __asan_get_report_description();
@@ -59,7 +59,19 @@ __asan_on_error() {
// CHECK: sp: 0x[[SP:[0-9a-f]+]]
fprintf(stderr, "addr: " PTR_FMT "\n", addr);
// CHECK: addr: 0x[[ADDR:[0-9a-f]+]]
- fprintf(stderr, "type: %s\n", (is_write ? "write" : "read"));
+ auto at_name = [access_type]() {
+ switch (access_type) {
+ case 0:
+ return "read";
+ case 1:
+ return "write";
+ case 2:
+ return "assumption";
+ default:
+ __builtin_trap();
+ }
+ };
+ fprintf(stderr, "type: %s\n", at_name());
// CHECK: type: write
fprintf(stderr, "access_size: %zu\n", access_size);
// CHECK: access_size: 1
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 451a60c5b6ecd..fbc2e8b71039f 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -300,6 +300,11 @@ static cl::opt<bool> ClRedzoneByvalArgs("asan-redzone-byval-args",
"required)"), cl::Hidden,
cl::init(true));
+static cl::opt<bool> ClInstrumentAssumeDereferenceable(
+ "asan-instrument-assume-dereferenceable",
+ cl::desc("instrument llvm.assume(dereferenceable)"), cl::Hidden,
+ cl::init(false));
+
static cl::opt<bool> ClUseAfterScope("asan-use-after-scope",
cl::desc("Check stack-use-after-scope"),
cl::Hidden, cl::init(false));
@@ -945,6 +950,7 @@ struct AddressSanitizer {
// These arrays is indexed by AccessIsWrite and Experiment.
FunctionCallee AsanErrorCallbackSized[2][2];
FunctionCallee AsanMemoryAccessCallbackSized[2][2];
+ FunctionCallee AsanAssumeDereferenceableCallback;
FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
Value *LocalDynamicShadow = nullptr;
@@ -2947,6 +2953,12 @@ bool ModuleAddressSanitizer::instrumentModule() {
void AddressSanitizer::initializeCallbacks(const TargetLibraryInfo *TLI) {
IRBuilder<> IRB(*C);
+
+ const std::string EndingStr = Recover ? "_noabort" : "";
+ AsanAssumeDereferenceableCallback = M.getOrInsertFunction(
+ "__asan_report_assume_dereferenceable" + EndingStr,
+ FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false));
+
// Create __asan_report* callbacks.
// IsWrite, TypeSize and Exp are encoded in the function name.
for (int Exp = 0; Exp < 2; Exp++) {
@@ -3168,6 +3180,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
SmallVector<Instruction *, 8> NoReturnCalls;
SmallVector<BasicBlock *, 16> AllBlocks;
SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts;
+ SmallVector<AssumeInst *, 8> DerefAssumptions;
// Fill the set of memory operations to instrument.
for (auto &BB : F) {
@@ -3182,6 +3195,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
PiJoules
force-pushed
the
reland-asan-assume-deref
branch
from
September 16, 2026 23:20
9194447 to
0db16f0
Compare
…ferencable" This relands commit bf8cf4b (llvm#190871), which was reverted in commit e3b3706 (llvm#193655). This checks that the range covered by this intrinsic is dereferenceable. Specifically it checks for `llvm.assume` intrinsics using the `dereferenceable` operator bundle and asserts that the shadow for this range is zero. Fixes included in this reland: 1. Darwin Stable ABI: Added __asan_report_assume_dereferenceable and __asan_report_assume_dereferenceable_noabort to asan_abi_tbd.txt to resolve the interface symbols diff failure in llvm_interface_symbols.cpp. 2. MSVC Support: Added UNSUPPORTED: msvc to the new assume_dereferenceable*.cpp tests, as __builtin_assume_dereferenceable is a Clang builtin not supported by MSVC's compiler frontend. 3. Stack instrumentation in tests: Added dummy memory accesses to test_stack_partial_right() and test_stack_partial_left() in assume_dereferenceable.cpp so that ASan instruments the stack frame and creates poisoned redzones as expected. 4. Default flag: Set -asan-instrument-assume-dereferenceable default to false for initial baking to prevent unexpected failures on bootstrap builders. 5. Merge conflict resolution with llvm#181446: Updated __asan_get_report_src_address and __asan_get_report_dest_address to check `access_type` instead of `is_write`.
PiJoules
force-pushed
the
reland-asan-assume-deref
branch
from
September 17, 2026 03:49
0db16f0 to
4f2cf57
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This relands commit bf8cf4b (#190871), which was reverted in commit e3b3706 (#193655).
This checks that the range covered by this intrinsic is dereferenceable. Specifically it checks for
llvm.assumeintrinsics using thedereferenceableoperator bundle and asserts that the shadow for this range is zero.Fixes included in this reland:
__asan_report_assume_dereferenceableand__asan_report_assume_dereferenceable_noaborttoasan_abi_tbd.txtto resolve the interface symbols diff failure in llvm_interface_symbols.cpp.UNSUPPORTED: msvcto the newassume_dereferenceable*.cpptests, as__builtin_assume_dereferenceableis a Clang builtin not supported by MSVC's compiler frontend.test_stack_partial_right()andtest_stack_partial_left()inassume_dereferenceable.cppso that ASan instruments the stack frame and creates poisoned redzones as expected.-asan-instrument-assume-dereferenceabledefault to false for initial baking to prevent unexpected failures on bootstrap builders.