[compiler-rt] 20edc84 - [compiler-rt][TySan] Use pointer-width types for shadow memory ops (#191602)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 07:11:53 PDT 2026


Author: Brian Cain
Date: 2026-04-14T09:11:47-05:00
New Revision: 20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8

URL: https://github.com/llvm/llvm-project/commit/20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8
DIFF: https://github.com/llvm/llvm-project/commit/20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8.diff

LOG: [compiler-rt][TySan] Use pointer-width types for shadow memory ops (#191602)

The TySan runtime used uint64_t/int64_t casts for shadow memory pointer
arithmetic and interior-byte marker values. These are incorrect on
32-bit targets where pointers are 4 bytes: the shadow entries are
pointer-sized, so the offsets and marker values must also be
pointer-sized.

Replace uint64_t/int64_t with uptr/sptr (sanitizer_common's
pointer-width typedefs) throughout SetShadowType, GetNotAllBadTD,
GetNotAllUnkTD, and __tysan_instrument_mem_inst. This is a no-op on
64-bit targets (where uptr == uint64_t) and fixes shadow corruption on
32-bit targets.

Added: 
    

Modified: 
    compiler-rt/lib/tysan/tysan.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp
index 52f941180b8eb..7c1cf193d3cb6 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -265,33 +265,33 @@ static void SetShadowType(tysan_type_descriptor *td,
                           tysan_type_descriptor **shadowData,
                           uint64_t AccessSize) {
   *shadowData = td;
-  uint64_t shadowDataInt = (uint64_t)shadowData;
+  uptr shadowDataInt = (uptr)shadowData;
 
   for (uint64_t i = 1; i < AccessSize; ++i) {
-    int64_t dataOffset = i << PtrShift();
-    int64_t *badShadowData = (int64_t *)(shadowDataInt + dataOffset);
-    int64_t badTD = int64_t(i) * -1;
+    uptr dataOffset = i << PtrShift();
+    sptr *badShadowData = (sptr *)(shadowDataInt + dataOffset);
+    sptr badTD = sptr(i) * -1;
     *badShadowData = badTD;
   }
 }
 
 ALWAYS_INLINE
-static bool GetNotAllBadTD(uint64_t ShadowDataInt, uint64_t AccessSize) {
+static bool GetNotAllBadTD(uptr ShadowDataInt, uint64_t AccessSize) {
   bool notAllBadTD = false;
   for (uint64_t i = 1; i < AccessSize; ++i) {
-    int64_t **unkShadowData = (int64_t **)(ShadowDataInt + (i << PtrShift()));
-    int64_t *ILdTD = *unkShadowData;
+    sptr **unkShadowData = (sptr **)(ShadowDataInt + (i << PtrShift()));
+    sptr *ILdTD = *unkShadowData;
     notAllBadTD = notAllBadTD || (ILdTD != nullptr);
   }
   return notAllBadTD;
 }
 
 ALWAYS_INLINE
-static bool GetNotAllUnkTD(uint64_t ShadowDataInt, uint64_t AccessSize) {
+static bool GetNotAllUnkTD(uptr ShadowDataInt, uint64_t AccessSize) {
   bool notAllBadTD = false;
   for (uint64_t i = 1; i < AccessSize; ++i) {
-    int64_t *badShadowData = (int64_t *)(ShadowDataInt + (i << PtrShift()));
-    int64_t ILdTD = *badShadowData;
+    sptr *badShadowData = (sptr *)(ShadowDataInt + (i << PtrShift()));
+    sptr ILdTD = *badShadowData;
     notAllBadTD = notAllBadTD || (ILdTD >= 0);
   }
   return notAllBadTD;
@@ -307,9 +307,8 @@ __tysan_instrument_mem_inst(char *dest, char *src, uint64_t size,
     return;
   }
 
-  uint64_t srcInt = (uint64_t)src;
-  uint64_t srcShadowInt = ((srcInt & AppMask()) << PtrShift()) + ShadowAddr();
-  uint64_t *srcShadow = (uint64_t *)srcShadowInt;
+  uptr srcShadowInt = ((((uptr)src) & AppMask()) << PtrShift()) + ShadowAddr();
+  void *srcShadow = (void *)srcShadowInt;
 
   if (needsMemMove) {
     internal_memmove((char *)destShadowDataPtr, srcShadow, size << PtrShift());
@@ -389,7 +388,7 @@ __tysan_instrument_with_shadow_update(void *ptr, tysan_type_descriptor *td,
       if (shadowIsNull) {
         // We're about to set the type. Make sure that all bytes in the value
         // are also of unknown type.
-        bool isAllUnknownTD = GetNotAllUnkTD((uint64_t)shadowData, accessSize);
+        bool isAllUnknownTD = GetNotAllUnkTD((uptr)shadowData, accessSize);
         if (isAllUnknownTD) {
           GET_CALLER_PC_BP_SP;
           __tysan_check_internal(ptr, accessSize, td, flags, pc, bp, sp);
@@ -402,7 +401,7 @@ __tysan_instrument_with_shadow_update(void *ptr, tysan_type_descriptor *td,
     } else {
       // We appear to have the right type. Make sure that all other bytes in
       // the type are still marked as interior bytes. If not, call the runtime.
-      bool isNotAllBadTD = GetNotAllBadTD((uint64_t)shadowData, accessSize);
+      bool isNotAllBadTD = GetNotAllBadTD((uptr)shadowData, accessSize);
       if (isNotAllBadTD) {
         GET_CALLER_PC_BP_SP;
         __tysan_check_internal(ptr, accessSize, td, flags, pc, bp, sp);


        


More information about the llvm-commits mailing list