[compiler-rt] [asan] API for getting multiple pointer ranges (PR #181446)
Maksim Ivanov via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 14:58:25 PDT 2026
https://github.com/emaxx-google updated https://github.com/llvm/llvm-project/pull/181446
>From 4c21a9ec78a457313c31918d5703e926aff3d9fc Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Fri, 13 Feb 2026 20:36:54 +0100
Subject: [PATCH 1/7] [asan] API for getting multiple pointer ranges
Add an API that, unlike __asan_get_report_address(), can return multiple
addresses and sizes. E.g., a handler might be interested in inspecting
the source and the destination ranges of a memcpy-param-overlap error.
---
.../include/sanitizer/asan_interface.h | 24 ++++
compiler-rt/lib/asan/asan_errors.h | 8 +-
.../asan/asan_interceptors_memintrinsics.h | 50 ++++----
.../lib/asan/asan_interface_internal.h | 12 ++
compiler-rt/lib/asan/asan_report.cpp | 108 +++++++++++++++++-
compiler-rt/lib/asan/asan_report.h | 4 +-
6 files changed, 173 insertions(+), 33 deletions(-)
diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 544f2e4b32687..5de4ea1ca5794 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -174,6 +174,30 @@ int SANITIZER_CDECL __asan_get_report_access_type(void);
/// \returns Access size in bytes.
size_t SANITIZER_CDECL __asan_get_report_access_size(void);
+typedef enum {
+ // Source address (e.g. memcpy source, or the address being read from).
+ __asan_address_info_src = 1,
+ // Destination address (e.g. memcpy dest, or the address being written to).
+ __asan_address_info_dest = 2,
+ // Address being deallocated (lifetime is terminated).
+ __asan_address_info_dealloc = 3,
+ // First non-dereferenced operand (e.g. pointer comparison, ODR definition).
+ __asan_address_info_first = 4,
+ // Second non-dereferenced operand (e.g. pointer comparison, ODR definition).
+ __asan_address_info_second = 5,
+} __asan_address_info_type;
+
+/// Gets a specific address or address range involved in the current error.
+///
+/// \param type __asan_address_info_type which the info is requested for.
+/// \param out_addr [out] Storage for the address.
+/// \param out_size [out] Storage for the range size. Zero may be reported
+/// (e.g., for pointer comparison errors as no dereferencing occurs).
+///
+/// \returns 1 if found, 0 otherwise.
+int SANITIZER_CDECL __asan_get_report_address_info(int type, void **out_addr,
+ size_t *out_size);
+
/// Gets the bug description of an ASan error (useful for calling from a
/// debugger).
///
diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h
index f339b35d2a764..06ec69f0f4547 100644
--- a/compiler-rt/lib/asan/asan_errors.h
+++ b/compiler-rt/lib/asan/asan_errors.h
@@ -301,14 +301,16 @@ struct ErrorStringFunctionSizeOverflow : ErrorBase {
const BufferedStackTrace *stack;
AddressDescription addr_description;
uptr size;
+ bool is_write;
ErrorStringFunctionSizeOverflow() = default; // (*)
- ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
- uptr addr, uptr size_)
+ ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace* stack_,
+ uptr addr, uptr size_, bool is_write_)
: ErrorBase(tid, 10, "negative-size-param"),
stack(stack_),
addr_description(addr, /*shouldLockThreadRegistry=*/false),
- size(size_) {}
+ size(size_),
+ is_write(is_write_) {}
void Print();
};
diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h
index ec988cff51c59..f7759caf68e2c 100644
--- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h
+++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h
@@ -53,31 +53,31 @@ struct AsanInterceptorContext {
// that no extra frames are created, and stack trace contains
// relevant information only.
// We check all shadow bytes.
-#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) \
- do { \
- uptr __offset = (uptr)(offset); \
- uptr __size = (uptr)(size); \
- uptr __bad = 0; \
- if (UNLIKELY(__offset > __offset + __size)) { \
- GET_STACK_TRACE_FATAL_HERE; \
- ReportStringFunctionSizeOverflow(__offset, __size, &stack); \
- } \
- if (UNLIKELY(!QuickCheckForUnpoisonedRegion(__offset, __size)) && \
- (__bad = __asan_region_is_poisoned(__offset, __size))) { \
- AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \
- bool suppressed = false; \
- if (_ctx) { \
- suppressed = IsInterceptorSuppressed(_ctx->interceptor_name); \
- if (!suppressed && HaveStackTraceBasedSuppressions()) { \
- GET_STACK_TRACE_FATAL_HERE; \
- suppressed = IsStackTraceSuppressed(&stack); \
- } \
- } \
- if (!suppressed) { \
- GET_CURRENT_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false); \
- } \
- } \
+#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) \
+ do { \
+ uptr __offset = (uptr)(offset); \
+ uptr __size = (uptr)(size); \
+ uptr __bad = 0; \
+ if (UNLIKELY(__offset > __offset + __size)) { \
+ GET_STACK_TRACE_FATAL_HERE; \
+ ReportStringFunctionSizeOverflow(__offset, __size, isWrite, &stack); \
+ } \
+ if (UNLIKELY(!QuickCheckForUnpoisonedRegion(__offset, __size)) && \
+ (__bad = __asan_region_is_poisoned(__offset, __size))) { \
+ AsanInterceptorContext* _ctx = (AsanInterceptorContext*)ctx; \
+ bool suppressed = false; \
+ if (_ctx) { \
+ suppressed = IsInterceptorSuppressed(_ctx->interceptor_name); \
+ if (!suppressed && HaveStackTraceBasedSuppressions()) { \
+ GET_STACK_TRACE_FATAL_HERE; \
+ suppressed = IsStackTraceSuppressed(&stack); \
+ } \
+ } \
+ if (!suppressed) { \
+ GET_CURRENT_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false); \
+ } \
+ } \
} while (0)
#define ASAN_READ_RANGE(ctx, offset, size) \
diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h
index a998263780221..ab09c5028f587 100644
--- a/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/compiler-rt/lib/asan/asan_interface_internal.h
@@ -157,6 +157,18 @@ extern "C" {
int __asan_get_report_access_type();
SANITIZER_INTERFACE_ATTRIBUTE
uptr __asan_get_report_access_size();
+
+ typedef enum {
+ __asan_address_info_src = 1,
+ __asan_address_info_dest = 2,
+ __asan_address_info_dealloc = 3,
+ __asan_address_info_first = 4,
+ __asan_address_info_second = 5,
+ } __asan_address_info_type;
+
+ SANITIZER_INTERFACE_ATTRIBUTE
+ int __asan_get_report_address_info(int type, uptr* out_addr, uptr* out_size);
+
SANITIZER_INTERFACE_ATTRIBUTE
const char * __asan_get_report_description();
diff --git a/compiler-rt/lib/asan/asan_report.cpp b/compiler-rt/lib/asan/asan_report.cpp
index e049a21e4e16d..e19626934e272 100644
--- a/compiler-rt/lib/asan/asan_report.cpp
+++ b/compiler-rt/lib/asan/asan_report.cpp
@@ -366,11 +366,11 @@ void ReportStringFunctionMemoryRangesOverlap(const char *function,
in_report.ReportError(error);
}
-void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack) {
+void ReportStringFunctionSizeOverflow(uptr offset, uptr size, bool is_write,
+ BufferedStackTrace* stack) {
ScopedInErrorReport in_report;
ErrorStringFunctionSizeOverflow error(GetCurrentTidOrInvalid(), stack, offset,
- size);
+ size, is_write);
in_report.ReportError(error);
}
@@ -602,6 +602,108 @@ uptr __asan_get_report_access_size() {
return 0;
}
+int __asan_get_report_address_info(int type, uptr* out_addr, uptr* out_size) {
+ ErrorDescription& err = ScopedInErrorReport::CurrentError();
+ switch (type) {
+ case __asan_address_info_src:
+ if (err.kind == kErrorKindGeneric && !err.Generic.is_write) {
+ *out_addr = err.Generic.addr_description.Address();
+ *out_size = err.Generic.access_size;
+ return 1;
+ }
+ if (err.kind == kErrorKindStringFunctionMemoryRangesOverlap) {
+ *out_addr =
+ err.StringFunctionMemoryRangesOverlap.addr2_description.Address();
+ *out_size = err.StringFunctionMemoryRangesOverlap.length2;
+ return 1;
+ }
+ if (err.kind == kErrorKindStringFunctionSizeOverflow &&
+ !err.StringFunctionSizeOverflow.is_write) {
+ *out_addr = err.StringFunctionSizeOverflow.addr_description.Address();
+ *out_size = err.StringFunctionSizeOverflow.size;
+ return 1;
+ }
+ if (err.kind == kErrorKindMallocUsableSizeNotOwned) {
+ *out_addr = err.MallocUsableSizeNotOwned.addr_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ if (err.kind == kErrorKindSanitizerGetAllocatedSizeNotOwned) {
+ *out_addr =
+ err.SanitizerGetAllocatedSizeNotOwned.addr_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ break;
+ case __asan_address_info_dest:
+ if (err.kind == kErrorKindGeneric && err.Generic.is_write) {
+ *out_addr = err.Generic.addr_description.Address();
+ *out_size = err.Generic.access_size;
+ return 1;
+ }
+ if (err.kind == kErrorKindStringFunctionMemoryRangesOverlap) {
+ *out_addr =
+ err.StringFunctionMemoryRangesOverlap.addr1_description.Address();
+ *out_size = err.StringFunctionMemoryRangesOverlap.length1;
+ return 1;
+ }
+ if (err.kind == kErrorKindStringFunctionSizeOverflow &&
+ err.StringFunctionSizeOverflow.is_write) {
+ *out_addr = err.StringFunctionSizeOverflow.addr_description.Address();
+ *out_size = err.StringFunctionSizeOverflow.size;
+ return 1;
+ }
+ break;
+ case __asan_address_info_dealloc:
+ if (err.kind == kErrorKindDoubleFree) {
+ *out_addr = err.DoubleFree.addr_description.addr;
+ *out_size = 0;
+ return 1;
+ }
+ if (err.kind == kErrorKindNewDeleteTypeMismatch) {
+ *out_addr = err.NewDeleteTypeMismatch.addr_description.addr;
+ *out_size = err.NewDeleteTypeMismatch.delete_size;
+ return 1;
+ }
+ if (err.kind == kErrorKindFreeNotMalloced) {
+ *out_addr = err.FreeNotMalloced.addr_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ if (err.kind == kErrorKindAllocTypeMismatch) {
+ *out_addr = err.AllocTypeMismatch.addr_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ break;
+ case __asan_address_info_first:
+ if (err.kind == kErrorKindInvalidPointerPair) {
+ *out_addr = err.InvalidPointerPair.addr1_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ if (err.kind == kErrorKindODRViolation) {
+ *out_addr = err.ODRViolation.global1.beg;
+ *out_size = 0;
+ return 1;
+ }
+ break;
+ case __asan_address_info_second:
+ if (err.kind == kErrorKindInvalidPointerPair) {
+ *out_addr = err.InvalidPointerPair.addr2_description.Address();
+ *out_size = 0;
+ return 1;
+ }
+ if (err.kind == kErrorKindODRViolation) {
+ *out_addr = err.ODRViolation.global2.beg;
+ *out_size = 0;
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
const char *__asan_get_report_description() {
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
return ScopedInErrorReport::CurrentError().Generic.bug_descr;
diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h
index 3143d83abe390..b6c2b3eae7c70 100644
--- a/compiler-rt/lib/asan/asan_report.h
+++ b/compiler-rt/lib/asan/asan_report.h
@@ -79,8 +79,8 @@ void ReportStringFunctionMemoryRangesOverlap(const char *function,
const char *offset1, uptr length1,
const char *offset2, uptr length2,
BufferedStackTrace *stack);
-void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack);
+void ReportStringFunctionSizeOverflow(uptr offset, uptr size, bool is_write,
+ BufferedStackTrace* stack);
void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
uptr old_mid, uptr new_mid,
BufferedStackTrace *stack);
>From 379055a29067e979bacb33a1c044e99bcf91d7fe Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Sat, 14 Feb 2026 03:44:14 +0100
Subject: [PATCH 2/7] update interface.inc
---
compiler-rt/lib/asan/asan_interface.inc | 1 +
1 file changed, 1 insertion(+)
diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
index b465356b1e443..7cbc4e636b5ab 100644
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -33,6 +33,7 @@ INTERFACE_FUNCTION(__asan_get_free_stack)
INTERFACE_FUNCTION(__asan_get_report_access_size)
INTERFACE_FUNCTION(__asan_get_report_access_type)
INTERFACE_FUNCTION(__asan_get_report_address)
+INTERFACE_FUNCTION(__asan_get_report_address_info)
INTERFACE_FUNCTION(__asan_get_report_bp)
INTERFACE_FUNCTION(__asan_get_report_description)
INTERFACE_FUNCTION(__asan_get_report_pc)
>From da2057867403b0b9089d3614b3c27b9a150106ed Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Mon, 16 Feb 2026 19:57:30 +0100
Subject: [PATCH 3/7] comment wording
---
compiler-rt/include/sanitizer/asan_interface.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 5de4ea1ca5794..739781f00f6b9 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -181,9 +181,9 @@ typedef enum {
__asan_address_info_dest = 2,
// Address being deallocated (lifetime is terminated).
__asan_address_info_dealloc = 3,
- // First non-dereferenced operand (e.g. pointer comparison, ODR definition).
+ // First non-dereferenced operand (e.g. pointer comparison, ODR violation).
__asan_address_info_first = 4,
- // Second non-dereferenced operand (e.g. pointer comparison, ODR definition).
+ // Second non-dereferenced operand (e.g. pointer comparison, ODR violation).
__asan_address_info_second = 5,
} __asan_address_info_type;
>From 85fe104f74aa84f897516102cc649185e1630501 Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Tue, 14 Apr 2026 15:35:44 +0200
Subject: [PATCH 4/7] tests, polish
---
.../include/sanitizer/asan_interface.h | 1 +
compiler-rt/lib/asan/asan_errors.h | 14 ++---
.../test/asan/TestCases/debug_double_free.cpp | 6 ++
.../TestCases/debug_invalid_pointer_pair.cpp | 55 +++++++++++++++++
.../asan/TestCases/debug_memcpy_overlap.cpp | 58 ++++++++++++++++++
.../asan/TestCases/debug_negative_size.cpp | 60 +++++++++++++++++++
.../test/asan/TestCases/debug_report.cpp | 10 ++++
7 files changed, 197 insertions(+), 7 deletions(-)
create mode 100644 compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
create mode 100644 compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
create mode 100644 compiler-rt/test/asan/TestCases/debug_negative_size.cpp
diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 739781f00f6b9..777e0ccb54e3c 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -175,6 +175,7 @@ int SANITIZER_CDECL __asan_get_report_access_type(void);
size_t SANITIZER_CDECL __asan_get_report_access_size(void);
typedef enum {
+ __asan_address_info_none = 0,
// Source address (e.g. memcpy source, or the address being read from).
__asan_address_info_src = 1,
// Destination address (e.g. memcpy dest, or the address being written to).
diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h
index 06ec69f0f4547..607e332b93d47 100644
--- a/compiler-rt/lib/asan/asan_errors.h
+++ b/compiler-rt/lib/asan/asan_errors.h
@@ -279,16 +279,16 @@ struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
const char *function;
ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
- ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
- uptr addr1, uptr length1_, uptr addr2,
- uptr length2_, const char *function_)
+ ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack,
+ uptr addr1, uptr length1, uptr addr2,
+ uptr length2, const char *function)
: ErrorBase(tid),
- stack(stack_),
- length1(length1_),
- length2(length2_),
+ stack(stack),
+ length1(length1),
+ length2(length2),
addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
- function(function_) {
+ function(function) {
char bug_type[100];
internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
scariness.Clear();
diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
index c1cc383b3c1e3..59f988aff89d1 100644
--- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
@@ -50,6 +50,12 @@ __asan_on_error() {
// CHECK: addr: {{0x0*}}[[ADDR]]
fprintf(stderr, "description: %s\n", description);
// CHECK: description: double-free
+
+ void *addr_dealloc = NULL;
+ size_t size_dealloc = 0;
+ int is_dealloc = __asan_get_report_address_info(__asan_address_info_dealloc, &addr_dealloc, &size_dealloc);
+ fprintf(stderr, "is_dealloc: %d, addr_dealloc: " PTR_FMT ", size_dealloc: %ld\n", is_dealloc, addr_dealloc, size_dealloc);
+ // CHECK: is_dealloc: 1, addr_dealloc: 0x[[ADDR]], size_dealloc: 0
}
// CHECK: AddressSanitizer: attempting double-free on {{0x0*}}[[ADDR]] in thread T0
diff --git a/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
new file mode 100644
index 0000000000000..9c2b67af768e0
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
@@ -0,0 +1,55 @@
+// Checks that the ASan debugging API for getting report information
+// returns correct values for invalid pointer pairs.
+// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair && %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/asan_interface.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *p;
+char *q;
+
+int main() {
+ // Disable stderr buffering. Needed on Windows.
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ p = (char *)malloc(42);
+ q = (char *)malloc(42);
+
+ fprintf(stderr, "p: %p\n", p);
+ // CHECK: p: 0x[[ADDR1:[0-9a-f]+]]
+ fprintf(stderr, "q: %p\n", q);
+ // CHECK: q: 0x[[ADDR2:[0-9a-f]+]]
+
+ // Trigger invalid pointer pair
+ int res = p > q; // BOOM
+
+ free(p);
+ free(q);
+ return res;
+}
+
+// Required for dyld macOS 12.0+
+#if (__APPLE__)
+__attribute__((weak))
+#endif
+extern "C" void
+__asan_on_error() {
+ int present = __asan_report_present();
+ fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
+ // CHECK: report
+
+ void *addr_first = NULL;
+ size_t size_first = 0;
+ int is_first = __asan_get_report_address_info(__asan_address_info_first, &addr_first, &size_first);
+ fprintf(stderr, "is_first: %d, addr_first: %p, size_first: %ld\n", is_first, addr_first, size_first);
+ // CHECK: is_first: 1, addr_first: 0x[[ADDR1]], size_first: 0
+
+ void *addr_second = NULL;
+ size_t size_second = 0;
+ int is_second = __asan_get_report_address_info(__asan_address_info_second, &addr_second, &size_second);
+ fprintf(stderr, "is_second: %d, addr_second: %p, size_second: %ld\n", is_second, addr_second, size_second);
+ // CHECK: is_second: 1, addr_second: 0x[[ADDR2]], size_second: 0
+}
+
+// CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
diff --git a/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp b/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
new file mode 100644
index 0000000000000..d57cdc3b7fa1c
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
@@ -0,0 +1,58 @@
+// Checks that the ASan debugging API for getting report information reports
+// memory overlap error details.
+// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/asan_interface.h>
+#include <stdio.h>
+#include <string.h>
+
+char buffer[10] = "hello";
+
+int main() {
+ // Disable stderr buffering. Needed on Windows.
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ // Trigger memcpy-param-overlap
+ memcpy(buffer, buffer + 1, 3); // BOOM
+ return 0;
+}
+
+// If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
+// lowercase hex.
+#ifdef _WIN32
+# ifdef _WIN64
+# define PTR_FMT "0x%08llx"
+# else
+# define PTR_FMT "0x%08x"
+# endif
+// Solaris libc omits the leading 0x.
+#elif defined(__sun__) && defined(__svr4__)
+# define PTR_FMT "0x%p"
+#else
+# define PTR_FMT "%p"
+#endif
+
+// Required for dyld macOS 12.0+
+#if (__APPLE__)
+__attribute__((weak))
+#endif
+extern "C" void
+__asan_on_error() {
+ int present = __asan_report_present();
+ fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
+ // CHECK: report
+
+ void *addr_src = NULL;
+ size_t size_src = 0;
+ int is_src = __asan_get_report_address_info(__asan_address_info_src, &addr_src, &size_src);
+ fprintf(stderr, "is_src: %d, addr_src: " PTR_FMT ", size_src: %ld\n", is_src, addr_src, size_src);
+ // CHECK: is_src: 1, addr_src: 0x{{[0-9a-f]+}}, size_src: 3
+
+ void *addr_dest = NULL;
+ size_t size_dest = 0;
+ int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr_dest, &size_dest);
+ fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT ", size_dest: %ld\n", is_dest, addr_dest, size_dest);
+ // CHECK: is_dest: 1, addr_dest: 0x{{[0-9a-f]+}}, size_dest: 3
+}
+
+// CHECK: memcpy-param-overlap
diff --git a/compiler-rt/test/asan/TestCases/debug_negative_size.cpp b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
new file mode 100644
index 0000000000000..396ea7311cf71
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
@@ -0,0 +1,60 @@
+// Checks that the ASan debugging API for getting report information
+// returns correct values for negative size parameter errors.
+// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/asan_interface.h>
+#include <stdio.h>
+#include <string.h>
+
+char buffer[10] = "hello";
+
+int main() {
+ // Disable stderr buffering. Needed on Windows.
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ // Trigger negative-size-param
+ memset(buffer, 0, (size_t)-1); // BOOM
+ return 0;
+}
+
+// If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
+// lowercase hex.
+#ifdef _WIN32
+# ifdef _WIN64
+# define PTR_FMT "0x%08llx"
+# else
+# define PTR_FMT "0x%08x"
+# endif
+// Solaris libc omits the leading 0x.
+#elif defined(__sun__) && defined(__svr4__)
+# define PTR_FMT "0x%p"
+#else
+# define PTR_FMT "%p"
+#endif
+
+// Required for dyld macOS 12.0+
+#if (__APPLE__)
+__attribute__((weak))
+#endif
+extern "C" void
+__asan_on_error() {
+ int present = __asan_report_present();
+ fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
+ // CHECK: report
+
+ void *addr_src = NULL;
+ size_t size_src = 0;
+ int is_src = __asan_get_report_address_info(__asan_address_info_src, &addr_src, &size_src);
+ fprintf(stderr, "is_src: %d\n", is_src);
+ // CHECK: is_src: 0
+
+ void *addr_dest = NULL;
+ size_t size_dest = 0;
+ int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr_dest, &size_dest);
+ // Do not format the size_dest because it is a very large number (-1 as size_t) and might be printed differently
+ // depending on the platform's size_t. We just check it's populated.
+ fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT "\n", is_dest, addr_dest);
+ // CHECK: is_dest: 1, addr_dest: 0x{{[0-9a-f]+}}
+}
+
+// CHECK: AddressSanitizer: negative-size-param
diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp
index 0dbb9f2fb9988..9c5f5032835af 100644
--- a/compiler-rt/test/asan/TestCases/debug_report.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_report.cpp
@@ -65,6 +65,16 @@ __asan_on_error() {
// CHECK: access_size: 1
fprintf(stderr, "description: %s\n", description);
// CHECK: description: heap-use-after-free
+
+ void *addr2 = NULL;
+ size_t size2 = 0;
+ int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr2, &size2);
+ fprintf(stderr, "is_dest: %d, addr2: " PTR_FMT ", size2: %ld\n", is_dest, addr2, size2);
+ // CHECK: is_dest: 1, addr2: 0x[[ADDR]], size2: 1
+
+ int is_none = __asan_get_report_address_info(__asan_address_info_none, &addr2, &size2);
+ fprintf(stderr, "is_none: %d\n", is_none);
+ // CHECK: is_none: 0
}
// CHECK: AddressSanitizer: heap-use-after-free on address {{0x0*}}[[ADDR]] at pc {{0x0*}}[[PC]] bp {{0x0*}}[[BP]] sp {{0x0*}}[[SP]]
>From d4dcf919f8848233ab16adf9ec7a5f0c8ae38a00 Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Tue, 14 Apr 2026 20:51:24 +0200
Subject: [PATCH 5/7] reformat; fix win test
---
compiler-rt/lib/asan/asan_errors.h | 4 +--
.../test/asan/TestCases/debug_double_free.cpp | 7 ++--
.../TestCases/debug_invalid_pointer_pair.cpp | 34 ++++++++++++++-----
.../asan/TestCases/debug_memcpy_overlap.cpp | 29 +++++++++-------
.../asan/TestCases/debug_negative_size.cpp | 23 +++++++------
.../test/asan/TestCases/debug_report.cpp | 11 +++---
6 files changed, 68 insertions(+), 40 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h
index 607e332b93d47..d821c3856d532 100644
--- a/compiler-rt/lib/asan/asan_errors.h
+++ b/compiler-rt/lib/asan/asan_errors.h
@@ -279,9 +279,9 @@ struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
const char *function;
ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
- ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack,
+ ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace* stack,
uptr addr1, uptr length1, uptr addr2,
- uptr length2, const char *function)
+ uptr length2, const char* function)
: ErrorBase(tid),
stack(stack),
length1(length1),
diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
index 59f988aff89d1..cfd67eebf13c4 100644
--- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
@@ -53,8 +53,11 @@ __asan_on_error() {
void *addr_dealloc = NULL;
size_t size_dealloc = 0;
- int is_dealloc = __asan_get_report_address_info(__asan_address_info_dealloc, &addr_dealloc, &size_dealloc);
- fprintf(stderr, "is_dealloc: %d, addr_dealloc: " PTR_FMT ", size_dealloc: %ld\n", is_dealloc, addr_dealloc, size_dealloc);
+ int is_dealloc = __asan_get_report_address_info(__asan_address_info_dealloc,
+ &addr_dealloc, &size_dealloc);
+ fprintf(stderr,
+ "is_dealloc: %d, addr_dealloc: " PTR_FMT ", size_dealloc: %zu\n",
+ is_dealloc, addr_dealloc, size_dealloc);
// CHECK: is_dealloc: 1, addr_dealloc: 0x[[ADDR]], size_dealloc: 0
}
diff --git a/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
index 9c2b67af768e0..2a299f92cceae 100644
--- a/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
@@ -6,6 +6,21 @@
#include <stdio.h>
#include <stdlib.h>
+// If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
+// lowercase hex.
+#ifdef _WIN32
+# ifdef _WIN64
+# define PTR_FMT "0x%08llx"
+# else
+# define PTR_FMT "0x%08x"
+# endif
+// Solaris libc omits the leading 0x.
+#elif defined(__sun__) && defined(__svr4__)
+# define PTR_FMT "0x%p"
+#else
+# define PTR_FMT "%p"
+#endif
+
char *p;
char *q;
@@ -16,9 +31,9 @@ int main() {
p = (char *)malloc(42);
q = (char *)malloc(42);
- fprintf(stderr, "p: %p\n", p);
+ fprintf(stderr, "p: " PTR_FMT "\n", p);
// CHECK: p: 0x[[ADDR1:[0-9a-f]+]]
- fprintf(stderr, "q: %p\n", q);
+ fprintf(stderr, "q: " PTR_FMT "\n", q);
// CHECK: q: 0x[[ADDR2:[0-9a-f]+]]
// Trigger invalid pointer pair
@@ -33,22 +48,25 @@ int main() {
#if (__APPLE__)
__attribute__((weak))
#endif
-extern "C" void
-__asan_on_error() {
+extern "C" void __asan_on_error() {
int present = __asan_report_present();
fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
// CHECK: report
void *addr_first = NULL;
size_t size_first = 0;
- int is_first = __asan_get_report_address_info(__asan_address_info_first, &addr_first, &size_first);
- fprintf(stderr, "is_first: %d, addr_first: %p, size_first: %ld\n", is_first, addr_first, size_first);
+ int is_first = __asan_get_report_address_info(__asan_address_info_first,
+ &addr_first, &size_first);
+ fprintf(stderr, "is_first: %d, addr_first: " PTR_FMT ", size_first: %zu\n",
+ is_first, addr_first, size_first);
// CHECK: is_first: 1, addr_first: 0x[[ADDR1]], size_first: 0
void *addr_second = NULL;
size_t size_second = 0;
- int is_second = __asan_get_report_address_info(__asan_address_info_second, &addr_second, &size_second);
- fprintf(stderr, "is_second: %d, addr_second: %p, size_second: %ld\n", is_second, addr_second, size_second);
+ int is_second = __asan_get_report_address_info(__asan_address_info_second,
+ &addr_second, &size_second);
+ fprintf(stderr, "is_second: %d, addr_second: " PTR_FMT ", size_second: %zu\n",
+ is_second, addr_second, size_second);
// CHECK: is_second: 1, addr_second: 0x[[ADDR2]], size_second: 0
}
diff --git a/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp b/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
index d57cdc3b7fa1c..276a91549c8c0 100644
--- a/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_memcpy_overlap.cpp
@@ -20,38 +20,41 @@ int main() {
// If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
// lowercase hex.
#ifdef _WIN32
-# ifdef _WIN64
-# define PTR_FMT "0x%08llx"
-# else
-# define PTR_FMT "0x%08x"
-# endif
+# ifdef _WIN64
+# define PTR_FMT "0x%08llx"
+# else
+# define PTR_FMT "0x%08x"
+# endif
// Solaris libc omits the leading 0x.
#elif defined(__sun__) && defined(__svr4__)
-# define PTR_FMT "0x%p"
+# define PTR_FMT "0x%p"
#else
-# define PTR_FMT "%p"
+# define PTR_FMT "%p"
#endif
// Required for dyld macOS 12.0+
#if (__APPLE__)
__attribute__((weak))
#endif
-extern "C" void
-__asan_on_error() {
+extern "C" void __asan_on_error() {
int present = __asan_report_present();
fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
// CHECK: report
void *addr_src = NULL;
size_t size_src = 0;
- int is_src = __asan_get_report_address_info(__asan_address_info_src, &addr_src, &size_src);
- fprintf(stderr, "is_src: %d, addr_src: " PTR_FMT ", size_src: %ld\n", is_src, addr_src, size_src);
+ int is_src = __asan_get_report_address_info(__asan_address_info_src,
+ &addr_src, &size_src);
+ fprintf(stderr, "is_src: %d, addr_src: " PTR_FMT ", size_src: %zu\n", is_src,
+ addr_src, size_src);
// CHECK: is_src: 1, addr_src: 0x{{[0-9a-f]+}}, size_src: 3
void *addr_dest = NULL;
size_t size_dest = 0;
- int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr_dest, &size_dest);
- fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT ", size_dest: %ld\n", is_dest, addr_dest, size_dest);
+ int is_dest = __asan_get_report_address_info(__asan_address_info_dest,
+ &addr_dest, &size_dest);
+ fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT ", size_dest: %zu\n",
+ is_dest, addr_dest, size_dest);
// CHECK: is_dest: 1, addr_dest: 0x{{[0-9a-f]+}}, size_dest: 3
}
diff --git a/compiler-rt/test/asan/TestCases/debug_negative_size.cpp b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
index 396ea7311cf71..ca1dc8a97c020 100644
--- a/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
@@ -20,37 +20,38 @@ int main() {
// If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
// lowercase hex.
#ifdef _WIN32
-# ifdef _WIN64
-# define PTR_FMT "0x%08llx"
-# else
-# define PTR_FMT "0x%08x"
-# endif
+# ifdef _WIN64
+# define PTR_FMT "0x%08llx"
+# else
+# define PTR_FMT "0x%08x"
+# endif
// Solaris libc omits the leading 0x.
#elif defined(__sun__) && defined(__svr4__)
-# define PTR_FMT "0x%p"
+# define PTR_FMT "0x%p"
#else
-# define PTR_FMT "%p"
+# define PTR_FMT "%p"
#endif
// Required for dyld macOS 12.0+
#if (__APPLE__)
__attribute__((weak))
#endif
-extern "C" void
-__asan_on_error() {
+extern "C" void __asan_on_error() {
int present = __asan_report_present();
fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
// CHECK: report
void *addr_src = NULL;
size_t size_src = 0;
- int is_src = __asan_get_report_address_info(__asan_address_info_src, &addr_src, &size_src);
+ int is_src = __asan_get_report_address_info(__asan_address_info_src,
+ &addr_src, &size_src);
fprintf(stderr, "is_src: %d\n", is_src);
// CHECK: is_src: 0
void *addr_dest = NULL;
size_t size_dest = 0;
- int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr_dest, &size_dest);
+ int is_dest = __asan_get_report_address_info(__asan_address_info_dest,
+ &addr_dest, &size_dest);
// Do not format the size_dest because it is a very large number (-1 as size_t) and might be printed differently
// depending on the platform's size_t. We just check it's populated.
fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT "\n", is_dest, addr_dest);
diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp
index 9c5f5032835af..06ef4d565098f 100644
--- a/compiler-rt/test/asan/TestCases/debug_report.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_report.cpp
@@ -61,18 +61,21 @@ __asan_on_error() {
// CHECK: addr: 0x[[ADDR:[0-9a-f]+]]
fprintf(stderr, "type: %s\n", (is_write ? "write" : "read"));
// CHECK: type: write
- fprintf(stderr, "access_size: %ld\n", access_size);
+ fprintf(stderr, "access_size: %zu\n", access_size);
// CHECK: access_size: 1
fprintf(stderr, "description: %s\n", description);
// CHECK: description: heap-use-after-free
void *addr2 = NULL;
size_t size2 = 0;
- int is_dest = __asan_get_report_address_info(__asan_address_info_dest, &addr2, &size2);
- fprintf(stderr, "is_dest: %d, addr2: " PTR_FMT ", size2: %ld\n", is_dest, addr2, size2);
+ int is_dest =
+ __asan_get_report_address_info(__asan_address_info_dest, &addr2, &size2);
+ fprintf(stderr, "is_dest: %d, addr2: " PTR_FMT ", size2: %zu\n", is_dest,
+ addr2, size2);
// CHECK: is_dest: 1, addr2: 0x[[ADDR]], size2: 1
- int is_none = __asan_get_report_address_info(__asan_address_info_none, &addr2, &size2);
+ int is_none =
+ __asan_get_report_address_info(__asan_address_info_none, &addr2, &size2);
fprintf(stderr, "is_none: %d\n", is_none);
// CHECK: is_none: 0
}
>From 476b715fcae5493adb5c0d9d4d9a291e96dc159e Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Tue, 14 Apr 2026 23:11:11 +0200
Subject: [PATCH 6/7] polish
---
compiler-rt/lib/asan/asan_errors.h | 10 +++++-----
compiler-rt/lib/asan/asan_interface_internal.h | 1 +
.../test/asan/TestCases/debug_negative_size.cpp | 9 +++++----
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h
index d821c3856d532..a9625c1477adf 100644
--- a/compiler-rt/lib/asan/asan_errors.h
+++ b/compiler-rt/lib/asan/asan_errors.h
@@ -304,13 +304,13 @@ struct ErrorStringFunctionSizeOverflow : ErrorBase {
bool is_write;
ErrorStringFunctionSizeOverflow() = default; // (*)
- ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace* stack_,
- uptr addr, uptr size_, bool is_write_)
+ ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace* stack, uptr addr,
+ uptr size, bool is_write)
: ErrorBase(tid, 10, "negative-size-param"),
- stack(stack_),
+ stack(stack),
addr_description(addr, /*shouldLockThreadRegistry=*/false),
- size(size_),
- is_write(is_write_) {}
+ size(size),
+ is_write(is_write) {}
void Print();
};
diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h
index ab09c5028f587..b9a2159ab3930 100644
--- a/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/compiler-rt/lib/asan/asan_interface_internal.h
@@ -159,6 +159,7 @@ extern "C" {
uptr __asan_get_report_access_size();
typedef enum {
+ __asan_address_info_none = 0,
__asan_address_info_src = 1,
__asan_address_info_dest = 2,
__asan_address_info_dealloc = 3,
diff --git a/compiler-rt/test/asan/TestCases/debug_negative_size.cpp b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
index ca1dc8a97c020..ac7e367dcd101 100644
--- a/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_negative_size.cpp
@@ -52,10 +52,11 @@ extern "C" void __asan_on_error() {
size_t size_dest = 0;
int is_dest = __asan_get_report_address_info(__asan_address_info_dest,
&addr_dest, &size_dest);
- // Do not format the size_dest because it is a very large number (-1 as size_t) and might be printed differently
- // depending on the platform's size_t. We just check it's populated.
- fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT "\n", is_dest, addr_dest);
- // CHECK: is_dest: 1, addr_dest: 0x{{[0-9a-f]+}}
+ // We check size_dest + 1 because size_dest is -1 (as size_t), which varies
+ // depending on the platform's size_t. Adding 1 should result in 0.
+ fprintf(stderr, "is_dest: %d, addr_dest: " PTR_FMT ", size_dest+1: %zu\n",
+ is_dest, addr_dest, size_dest + 1);
+ // CHECK: is_dest: 1, addr_dest: 0x{{[0-9a-f]+}}, size_dest+1: 0
}
// CHECK: AddressSanitizer: negative-size-param
>From 72668241763a1b4cdf06af5fad6654555052fe7e Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <emaxx at google.com>
Date: Tue, 14 Apr 2026 23:58:07 +0200
Subject: [PATCH 7/7] no tautological asserts
---
compiler-rt/test/asan/TestCases/debug_double_free.cpp | 2 +-
.../test/asan/TestCases/debug_invalid_pointer_pair.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
index cfd67eebf13c4..3804b6477ae60 100644
--- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
@@ -52,7 +52,7 @@ __asan_on_error() {
// CHECK: description: double-free
void *addr_dealloc = NULL;
- size_t size_dealloc = 0;
+ size_t size_dealloc = 0xbad;
int is_dealloc = __asan_get_report_address_info(__asan_address_info_dealloc,
&addr_dealloc, &size_dealloc);
fprintf(stderr,
diff --git a/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
index 2a299f92cceae..69d43b1a3fa4d 100644
--- a/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_invalid_pointer_pair.cpp
@@ -54,7 +54,7 @@ extern "C" void __asan_on_error() {
// CHECK: report
void *addr_first = NULL;
- size_t size_first = 0;
+ size_t size_first = 0xbad;
int is_first = __asan_get_report_address_info(__asan_address_info_first,
&addr_first, &size_first);
fprintf(stderr, "is_first: %d, addr_first: " PTR_FMT ", size_first: %zu\n",
@@ -62,7 +62,7 @@ extern "C" void __asan_on_error() {
// CHECK: is_first: 1, addr_first: 0x[[ADDR1]], size_first: 0
void *addr_second = NULL;
- size_t size_second = 0;
+ size_t size_second = 0xbad;
int is_second = __asan_get_report_address_info(__asan_address_info_second,
&addr_second, &size_second);
fprintf(stderr, "is_second: %d, addr_second: " PTR_FMT ", size_second: %zu\n",
More information about the llvm-commits
mailing list