[compiler-rt] [llvm] [TySan] Add initial user facing interfaces (PR #169023)

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 21 02:44:35 PST 2025


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions h,c,cpp -- compiler-rt/include/sanitizer/tysan_interface.h compiler-rt/lib/tysan/tysan_interface.cpp compiler-rt/lib/tysan/tysan_interface.h compiler-rt/test/tysan/interface-manipulate-shadow.c compiler-rt/test/tysan/interface-print-type.c compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp compiler-rt/lib/tysan/tysan.cpp compiler-rt/lib/tysan/tysan.h --diff_from_common_commit
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/compiler-rt/include/sanitizer/tysan_interface.h b/compiler-rt/include/sanitizer/tysan_interface.h
index 8cb35ae4b..e373baf03 100644
--- a/compiler-rt/include/sanitizer/tysan_interface.h
+++ b/compiler-rt/include/sanitizer/tysan_interface.h
@@ -20,20 +20,26 @@
 extern "C" {
 #endif
 
-// Copies the shadow memory for the source user memory into the shadow memory for the destination user memory
-void SANITIZER_CDECL __tysan_copy_shadow(const void *dst, const void *src, size_t type_size);
-
-// Copies the shadow memory for the source user memory into the shadow memory for each element in the
-// destination array in user memory 
-void SANITIZER_CDECL __tysan_copy_shadow_array(const void *dst_array, const void *src, size_t type_size, size_t arraySize);
+// Copies the shadow memory for the source user memory into the shadow memory
+// for the destination user memory
+void SANITIZER_CDECL __tysan_copy_shadow(const void *dst, const void *src,
+                                         size_t type_size);
+
+// Copies the shadow memory for the source user memory into the shadow memory
+// for each element in the destination array in user memory
+void SANITIZER_CDECL __tysan_copy_shadow_array(const void *dst_array,
+                                               const void *src,
+                                               size_t type_size,
+                                               size_t arraySize);
 
 // Clears the shadow memory for the given range of user memory.
 void SANITIZER_CDECL __tysan_reset_shadow(const void *addr, size_t size);
 
-// Writes the name of the type represented in the shadow memory for the given location in user memory
-// into the given buffer, up to the given size.
-// Returns the length written.
-int SANITIZER_CDECL __tysan_get_type_name(const void *addr, char *buffer, size_t buffer_size);
+// Writes the name of the type represented in the shadow memory for the given
+// location in user memory into the given buffer, up to the given size. Returns
+// the length written.
+int SANITIZER_CDECL __tysan_get_type_name(const void *addr, char *buffer,
+                                          size_t buffer_size);
 
 #ifdef __cplusplus
 }
diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp
index fdffe784d..780071304 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -56,9 +56,9 @@ static const char *getDisplayName(const char *Name) {
   return DName;
 }
 
-int getTDName(void *_td, char *buffer, uptr buffer_size, bool asset_on_error){
-  tysan_type_descriptor* td = (tysan_type_descriptor*)_td;
-  if(((sptr)td) <= 0){
+int getTDName(void *_td, char *buffer, uptr buffer_size, bool asset_on_error) {
+  tysan_type_descriptor *td = (tysan_type_descriptor *)_td;
+  if (((sptr)td) <= 0) {
     return internal_snprintf(buffer, buffer_size, "<unknown type>");
   }
 
@@ -73,14 +73,18 @@ int getTDName(void *_td, char *buffer, uptr buffer_size, bool asset_on_error){
   case TYSAN_MEMBER_TD:
     written = getTDName(td->Member.Access, buffer, buffer_size, false);
     if (td->Member.Access != td->Member.Base && written != buffer_size) {
-      written += internal_snprintf(&buffer[written], buffer_size - written, " (in ");
-      written += getTDName(td->Member.Base, &buffer[written], buffer_size - written, false);
-      written += internal_snprintf(&buffer[written], buffer_size - written, " at offset %zu)", td->Member.Offset);
+      written +=
+          internal_snprintf(&buffer[written], buffer_size - written, " (in ");
+      written += getTDName(td->Member.Base, &buffer[written],
+                           buffer_size - written, false);
+      written += internal_snprintf(&buffer[written], buffer_size - written,
+                                   " at offset %zu)", td->Member.Offset);
     }
     break;
   case TYSAN_STRUCT_TD:
-    written = internal_snprintf(buffer, buffer_size, "%s",
-      getDisplayName((char *)(td->Struct.Members + td->Struct.MemberCount)));
+    written = internal_snprintf(
+        buffer, buffer_size, "%s",
+        getDisplayName((char *)(td->Struct.Members + td->Struct.MemberCount)));
     break;
   }
   return written;
diff --git a/compiler-rt/lib/tysan/tysan_interface.cpp b/compiler-rt/lib/tysan/tysan_interface.cpp
index c2da6246b..4f6285f0d 100644
--- a/compiler-rt/lib/tysan/tysan_interface.cpp
+++ b/compiler-rt/lib/tysan/tysan_interface.cpp
@@ -1,4 +1,5 @@
-//===-- tysan_interface.inc --------------------------------------*- C++ -*-===//
+//===-- tysan_interface.inc --------------------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,26 +10,27 @@
 // This file is a part of TypeSanitizer.
 //
 //===----------------------------------------------------------------------===//
-#include "tysan.h"
 #include "tysan_interface.h"
+#include "tysan.h"
 
-void __tysan_copy_shadow(const void *dst, const void *src, size_t type_size){
-    tysan_copy_types(dst, src, type_size);
+void __tysan_copy_shadow(const void *dst, const void *src, size_t type_size) {
+  tysan_copy_types(dst, src, type_size);
 }
 
-void __tysan_copy_shadow_array(const void *dst_array, const void *src, size_t type_size, size_t arraySize){
-    const void* dst = dst_array;
-    for(size_t i = 0; i < arraySize; i++){
-        tysan_copy_types(dst, src, type_size);
-        dst = (void*)(((uptr)dst) + type_size);
-    }
+void __tysan_copy_shadow_array(const void *dst_array, const void *src,
+                               size_t type_size, size_t arraySize) {
+  const void *dst = dst_array;
+  for (size_t i = 0; i < arraySize; i++) {
+    tysan_copy_types(dst, src, type_size);
+    dst = (void *)(((uptr)dst) + type_size);
+  }
 }
 
-void __tysan_reset_shadow(const void *addr, size_t size){
-    tysan_set_type_unknown(addr, size);
+void __tysan_reset_shadow(const void *addr, size_t size) {
+  tysan_set_type_unknown(addr, size);
 }
 
-int __tysan_get_type_name(const void *addr, char *buffer, size_t buffer_size){
-    void** shadow = (void**)__tysan::shadow_for(addr);
-    return getTDName(*shadow, buffer, buffer_size, false);
+int __tysan_get_type_name(const void *addr, char *buffer, size_t buffer_size) {
+  void **shadow = (void **)__tysan::shadow_for(addr);
+  return getTDName(*shadow, buffer, buffer_size, false);
 }
diff --git a/compiler-rt/lib/tysan/tysan_interface.h b/compiler-rt/lib/tysan/tysan_interface.h
index 5a5e5cc08..8179fc395 100644
--- a/compiler-rt/lib/tysan/tysan_interface.h
+++ b/compiler-rt/lib/tysan/tysan_interface.h
@@ -1,4 +1,5 @@
-//===-- tysan_interface.h ----------------------------------------*- C++ -*-===//
+//===-- tysan_interface.h ----------------------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -27,7 +28,8 @@ SANITIZER_INTERFACE_ATTRIBUTE
 void __tysan_copy_shadow(const void *dst, const void *src, size_t type_size);
 
 SANITIZER_INTERFACE_ATTRIBUTE
-void __tysan_copy_shadow_array(const void *dst_array, const void *src, size_t type_size, size_t arraySize);
+void __tysan_copy_shadow_array(const void *dst_array, const void *src,
+                               size_t type_size, size_t arraySize);
 
 SANITIZER_INTERFACE_ATTRIBUTE
 void __tysan_reset_shadow(const void *addr, size_t size);
@@ -36,7 +38,7 @@ SANITIZER_INTERFACE_ATTRIBUTE
 int __tysan_get_type_name(const void *addr, char *buffer, size_t buffer_size);
 
 #ifdef __cplusplus
-}  // extern "C"
+} // extern "C"
 #endif
 
 #endif
diff --git a/compiler-rt/test/tysan/interface-manipulate-shadow.c b/compiler-rt/test/tysan/interface-manipulate-shadow.c
index 504de2876..25614e25e 100644
--- a/compiler-rt/test/tysan/interface-manipulate-shadow.c
+++ b/compiler-rt/test/tysan/interface-manipulate-shadow.c
@@ -8,92 +8,92 @@
 // shadow to prevent it from catching technically correct, yet harmless aliasing violations
 
 #ifdef BUILD_SO
-float useFloatArray(float* mem){
-    mem[0] = 2.f;
-    mem[1] = 3.f;
-    return mem[0] + mem[1];
+float useFloatArray(float *mem) {
+  mem[0] = 2.f;
+  mem[1] = 3.f;
+  return mem[0] + mem[1];
 }
 
-int useIntArray(int* mem){
-    mem[0] = 2;
-    mem[1] = 3;
-    mem[2] = 5;
-    return mem[0] + mem[1] + mem[2];
+int useIntArray(int *mem) {
+  mem[0] = 2;
+  mem[1] = 3;
+  mem[2] = 5;
+  return mem[0] + mem[1] + mem[2];
 }
 #else
 
-#include <assert.h>
-#include <dlfcn.h>
-#include <sanitizer/tysan_interface.h>
-#include <stdio.h>
+#  include <assert.h>
+#  include <dlfcn.h>
+#  include <sanitizer/tysan_interface.h>
+#  include <stdio.h>
 
-typedef float(*lib_func1_t)(float*);
-typedef int(*lib_func2_t)(int*);
+typedef float (*lib_func1_t)(float *);
+typedef int (*lib_func2_t)(int *);
 
-void print_flush(const char* message){
-    printf("%s\n", message);
-    fflush(stdout);
+void print_flush(const char *message) {
+  printf("%s\n", message);
+  fflush(stdout);
 }
 
-int main(int argc, char* argv[]){
-    assert(argc >=2);
-    void *libHandle = dlopen(argv[1], RTLD_LAZY);
-    assert(libHandle);
-
-    lib_func1_t useFloatArray = (lib_func1_t)dlsym(libHandle, "useFloatArray");
-    lib_func2_t useIntArray = (lib_func2_t)dlsym(libHandle, "useIntArray");
-
-    char memory[sizeof(int) * 3];
-    int iResult = 0;
-    float fResult = 0.f;
-    print_flush("Calling with omnipotent char memory");
-    fResult = useFloatArray((float*)memory);
-    print_flush("Shadow now has floats in");
-    iResult = useIntArray((int*)memory);
-
-// CHECK: Calling with omnipotent char memory
-// CHECK-NEXT: Shadow now has floats in
-// CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
-// CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type int accesses an existing object of type float
-    
-    __tysan_reset_shadow(memory, sizeof(memory));
-    print_flush("Shadow has been reset");
-    useIntArray((int*)memory);
-    print_flush("Completed int array");
-    
-// CHECK: Shadow has been reset
-// CHECK-NEXT: Completed int array
-
-    // Set shadow type to float
-    __tysan_copy_shadow_array(memory, &fResult, sizeof(float), 3);
-    print_flush("Float array with float set shadow");
-    useFloatArray((float*)memory);
-    print_flush("Int array with float set shadow");
-    useIntArray((int*)memory);
-
-// CHECK: Float array with float set shadow
-// CHECK-NEXT: Int array with float set shadow
-// CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
-// CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type int accesses an existing object of type float
-
-    // Set shadow type to int
-    for(size_t i = 0; i < 3; i++){
-        __tysan_copy_shadow(&memory[sizeof(int) * i], &iResult, sizeof(int));
-    }
-    print_flush("Float array with int set shadow");
-    useFloatArray((float*)memory);
-    print_flush("Int array with int set shadow");
-    useIntArray((int*)memory);
-    print_flush("Completed int array");
-
-// CHECK: Float array with int set shadow
-// CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
-// CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type float accesses an existing object of type int
-// CHECK: Int array with int set shadow
-// CHECK-NEXT: Completed int array
-
-    dlclose(libHandle);
-    return 0;
+int main(int argc, char *argv[]) {
+  assert(argc >= 2);
+  void *libHandle = dlopen(argv[1], RTLD_LAZY);
+  assert(libHandle);
+
+  lib_func1_t useFloatArray = (lib_func1_t)dlsym(libHandle, "useFloatArray");
+  lib_func2_t useIntArray = (lib_func2_t)dlsym(libHandle, "useIntArray");
+
+  char memory[sizeof(int) * 3];
+  int iResult = 0;
+  float fResult = 0.f;
+  print_flush("Calling with omnipotent char memory");
+  fResult = useFloatArray((float *)memory);
+  print_flush("Shadow now has floats in");
+  iResult = useIntArray((int *)memory);
+
+  // CHECK: Calling with omnipotent char memory
+  // CHECK-NEXT: Shadow now has floats in
+  // CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
+  // CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type int accesses an existing object of type float
+
+  __tysan_reset_shadow(memory, sizeof(memory));
+  print_flush("Shadow has been reset");
+  useIntArray((int *)memory);
+  print_flush("Completed int array");
+
+  // CHECK: Shadow has been reset
+  // CHECK-NEXT: Completed int array
+
+  // Set shadow type to float
+  __tysan_copy_shadow_array(memory, &fResult, sizeof(float), 3);
+  print_flush("Float array with float set shadow");
+  useFloatArray((float *)memory);
+  print_flush("Int array with float set shadow");
+  useIntArray((int *)memory);
+
+  // CHECK: Float array with float set shadow
+  // CHECK-NEXT: Int array with float set shadow
+  // CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
+  // CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type int accesses an existing object of type float
+
+  // Set shadow type to int
+  for (size_t i = 0; i < 3; i++) {
+    __tysan_copy_shadow(&memory[sizeof(int) * i], &iResult, sizeof(int));
+  }
+  print_flush("Float array with int set shadow");
+  useFloatArray((float *)memory);
+  print_flush("Int array with int set shadow");
+  useIntArray((int *)memory);
+  print_flush("Completed int array");
+
+  // CHECK: Float array with int set shadow
+  // CHECK-NEXT: ERROR: TypeSanitizer: type-aliasing-violation on address
+  // CHECK-NEXT: WRITE of size 4 at 0x{{.*}} with type float accesses an existing object of type int
+  // CHECK: Int array with int set shadow
+  // CHECK-NEXT: Completed int array
+
+  dlclose(libHandle);
+  return 0;
 }
 
 #endif
diff --git a/compiler-rt/test/tysan/interface-print-type.c b/compiler-rt/test/tysan/interface-print-type.c
index c61a7dc47..18c3bb0ce 100644
--- a/compiler-rt/test/tysan/interface-print-type.c
+++ b/compiler-rt/test/tysan/interface-print-type.c
@@ -4,30 +4,30 @@
 #include <sanitizer/tysan_interface.h>
 #include <stdio.h>
 
-struct S{
-    int i;
-    float f;
+struct S {
+  int i;
+  float f;
 };
 
-void printInt(int* i){
-    const int bufferSize = 512;
-    static char nameBuffer[bufferSize];
-    __tysan_get_type_name(i, nameBuffer, 512);
-    printf("%d, %s\n", *i, nameBuffer);
-    fflush(stdout);
+void printInt(int *i) {
+  const int bufferSize = 512;
+  static char nameBuffer[bufferSize];
+  __tysan_get_type_name(i, nameBuffer, 512);
+  printf("%d, %s\n", *i, nameBuffer);
+  fflush(stdout);
 }
 
-int main(){
-    struct S s;
-    s.i = 4;
-    printInt((int*)&s);
-// CHECK: 4, int (in S at offset 0)
+int main() {
+  struct S s;
+  s.i = 4;
+  printInt((int *)&s);
+  // CHECK: 4, int (in S at offset 0)
 
-    s.f = 5.0f;
-// CHECK: ERROR: TypeSanitizer: type-aliasing-violation
-// CHECK: READ of size 4 at 0x{{.*}} with type int accesses an existing object of type float (in S at offset 4)
-// CHECK: {{.*}}, float (in S at offset 4)
-    printInt((int*)&s.f);
+  s.f = 5.0f;
+  // CHECK: ERROR: TypeSanitizer: type-aliasing-violation
+  // CHECK: READ of size 4 at 0x{{.*}} with type int accesses an existing object of type float (in S at offset 4)
+  // CHECK: {{.*}}, float (in S at offset 4)
+  printInt((int *)&s.f);
 
-    return 0;
+  return 0;
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/169023


More information about the llvm-commits mailing list