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

Matthew Nagy via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 21 03:16:54 PST 2025


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

>From 489197778d233e21d0ca0ae46a8a3dca680a7233 Mon Sep 17 00:00:00 2001
From: gbMattN <matthew.nagy at sony.com>
Date: Thu, 20 Nov 2025 17:23:20 +0000
Subject: [PATCH 1/3] [TySan] add initial user facing interfaces

---
 compiler-rt/include/CMakeLists.txt            |  1 +
 .../include/sanitizer/tysan_interface.h       | 42 ++++++++
 .../tests/sanitizer_common_test.cpp           |  1 +
 compiler-rt/lib/tysan/CMakeLists.txt          |  2 +
 compiler-rt/lib/tysan/tysan.cpp               | 36 ++++---
 compiler-rt/lib/tysan/tysan.h                 |  2 +
 compiler-rt/lib/tysan/tysan_interface.cpp     | 34 +++++++
 compiler-rt/lib/tysan/tysan_interface.h       | 42 ++++++++
 .../test/tysan/interface-manipulate-shadow.c  | 99 +++++++++++++++++++
 compiler-rt/test/tysan/interface-print-type.c | 33 +++++++
 .../gn/secondary/compiler-rt/include/BUILD.gn |  1 +
 11 files changed, 281 insertions(+), 12 deletions(-)
 create mode 100644 compiler-rt/include/sanitizer/tysan_interface.h
 create mode 100644 compiler-rt/lib/tysan/tysan_interface.cpp
 create mode 100644 compiler-rt/lib/tysan/tysan_interface.h
 create mode 100644 compiler-rt/test/tysan/interface-manipulate-shadow.c
 create mode 100644 compiler-rt/test/tysan/interface-print-type.c

diff --git a/compiler-rt/include/CMakeLists.txt b/compiler-rt/include/CMakeLists.txt
index 242d62b9b447b..8443e309d1e95 100644
--- a/compiler-rt/include/CMakeLists.txt
+++ b/compiler-rt/include/CMakeLists.txt
@@ -14,6 +14,7 @@ if (COMPILER_RT_BUILD_SANITIZERS)
     sanitizer/scudo_interface.h
     sanitizer/tsan_interface.h
     sanitizer/tsan_interface_atomic.h
+    sanitizer/tysan_interface.h
     sanitizer/ubsan_interface.h
     )
   set(FUZZER_HEADERS
diff --git a/compiler-rt/include/sanitizer/tysan_interface.h b/compiler-rt/include/sanitizer/tysan_interface.h
new file mode 100644
index 0000000000000..8cb35ae4b5c09
--- /dev/null
+++ b/compiler-rt/include/sanitizer/tysan_interface.h
@@ -0,0 +1,42 @@
+//===-- tsan_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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of TypeSanitizer.
+//
+// Public interface header for TySan.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_TYSAN_INTERFACE_H
+#define SANITIZER_TYSAN_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+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);
+
+// 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
index 111e55ef36bfb..917ba847ad478 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
@@ -21,6 +21,7 @@
 #include "../../../include/sanitizer/asan_interface.h"
 #include "../../../include/sanitizer/msan_interface.h"
 #include "../../../include/sanitizer/tsan_interface.h"
+#include "../../../include/sanitizer/tysan_interface.h"
 #include "gtest/gtest.h"
 #include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_common.h"
diff --git a/compiler-rt/lib/tysan/CMakeLists.txt b/compiler-rt/lib/tysan/CMakeLists.txt
index 7d13ae3963919..a878a46322bd2 100644
--- a/compiler-rt/lib/tysan/CMakeLists.txt
+++ b/compiler-rt/lib/tysan/CMakeLists.txt
@@ -4,11 +4,13 @@ include_directories(..)
 set(TYSAN_SOURCES
   tysan.cpp
   tysan_interceptors.cpp
+  tysan_interface.cpp
   )
 
 SET(TYSAN_HEADERS
   tysan.h
   tysan_flags.inc
+  tysan_interface.h
   tysan_platform.h
   )
 
diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp
index 1c67adeba0fc5..fdffe784d0c74 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -56,29 +56,41 @@ static const char *getDisplayName(const char *Name) {
   return DName;
 }
 
-static void printTDName(tysan_type_descriptor *td) {
-  if (((sptr)td) <= 0) {
-    Printf("<unknown type>");
-    return;
+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>");
   }
 
+  uptr written = 0;
   switch (td->Tag) {
   default:
-    CHECK(false && "invalid enum value");
+    if (asset_on_error)
+      CHECK(false && "invalid enum value");
+    else
+      written = internal_snprintf(buffer, buffer_size, "<invalid shadow>");
     break;
   case TYSAN_MEMBER_TD:
-    printTDName(td->Member.Access);
-    if (td->Member.Access != td->Member.Base) {
-      Printf(" (in ");
-      printTDName(td->Member.Base);
-      Printf(" at offset %zu)", td->Member.Offset);
+    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);
     }
     break;
   case TYSAN_STRUCT_TD:
-    Printf("%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;
+}
+
+static void printTDName(tysan_type_descriptor *td) {
+  static const uptr nameBufferSize = 512;
+  static char nameBuffer[nameBufferSize];
+  getTDName(td, nameBuffer, nameBufferSize, true);
+  Printf("%s", nameBuffer);
 }
 
 static tysan_type_descriptor *getRootTD(tysan_type_descriptor *TD) {
diff --git a/compiler-rt/lib/tysan/tysan.h b/compiler-rt/lib/tysan/tysan.h
index 97df28037b0d2..b7b1306cf10bd 100644
--- a/compiler-rt/lib/tysan/tysan.h
+++ b/compiler-rt/lib/tysan/tysan.h
@@ -20,11 +20,13 @@ using __sanitizer::sptr;
 using __sanitizer::u16;
 using __sanitizer::uptr;
 
+#include "tysan_interface.h"
 #include "tysan_platform.h"
 
 extern "C" {
 void tysan_set_type_unknown(const void *addr, uptr size);
 void tysan_copy_types(const void *daddr, const void *saddr, uptr size);
+int getTDName(void *td, char *buffer, uptr buffer_size, bool assert_on_error);
 }
 
 namespace __tysan {
diff --git a/compiler-rt/lib/tysan/tysan_interface.cpp b/compiler-rt/lib/tysan/tysan_interface.cpp
new file mode 100644
index 0000000000000..c2da6246b0044
--- /dev/null
+++ b/compiler-rt/lib/tysan/tysan_interface.cpp
@@ -0,0 +1,34 @@
+//===-- 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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of TypeSanitizer.
+//
+//===----------------------------------------------------------------------===//
+#include "tysan.h"
+#include "tysan_interface.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_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);
+}
+
+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
new file mode 100644
index 0000000000000..5a5e5cc08d2b3
--- /dev/null
+++ b/compiler-rt/lib/tysan/tysan_interface.h
@@ -0,0 +1,42 @@
+//===-- 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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of TypeSanitizer.
+//
+// The functions declared in this header will be inserted by the instrumentation
+// module.
+// This header can be included by the instrumented program or by TySan tests.
+//===----------------------------------------------------------------------===//
+
+#ifndef TYSAN_INTERFACE_H
+#define TYSAN_INTERFACE_H
+
+#include <sanitizer_common/sanitizer_internal_defs.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tysan_reset_shadow(const void *addr, size_t size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __tysan_get_type_name(const void *addr, char *buffer, size_t buffer_size);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/compiler-rt/test/tysan/interface-manipulate-shadow.c b/compiler-rt/test/tysan/interface-manipulate-shadow.c
new file mode 100644
index 0000000000000..504de2876cf26
--- /dev/null
+++ b/compiler-rt/test/tysan/interface-manipulate-shadow.c
@@ -0,0 +1,99 @@
+// REQUIRES: system-linux || system-darwin
+// RUN: %clang_tysan %s -g -shared -fpic -o %t.so -DBUILD_SO
+// RUN: %clang_tysan %s -g -o %t
+// RUN: %run %t %t.so 2>&1 | FileCheck %s
+
+// Compilers can't optimize using type aliasing across the bounds of dynamic librarys
+// When passing memory between instrumented executables and dlls, you may want to alter TySan's
+// 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];
+}
+
+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>
+
+typedef float(*lib_func1_t)(float*);
+typedef int(*lib_func2_t)(int*);
+
+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;
+}
+
+#endif
diff --git a/compiler-rt/test/tysan/interface-print-type.c b/compiler-rt/test/tysan/interface-print-type.c
new file mode 100644
index 0000000000000..c61a7dc477353
--- /dev/null
+++ b/compiler-rt/test/tysan/interface-print-type.c
@@ -0,0 +1,33 @@
+// RUN: %clang_tysan %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/tysan_interface.h>
+#include <stdio.h>
+
+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);
+}
+
+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);
+
+    return 0;
+}
diff --git a/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
index 273fd7172da62..8e8ce837ef21e 100644
--- a/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
@@ -22,6 +22,7 @@ copy("include") {
     "sanitizer/scudo_interface.h",
     "sanitizer/tsan_interface.h",
     "sanitizer/tsan_interface_atomic.h",
+    sanitizer/tysan_interface.h
     "sanitizer/ubsan_interface.h",
   ]
   outputs = [ "$clang_resource_dir/include/{{source_target_relative}}" ]

>From 8123f51ee4c0afb26cc1ef0bc67ffd8b02557f42 Mon Sep 17 00:00:00 2001
From: gbMattN <matthew.nagy at sony.com>
Date: Fri, 21 Nov 2025 11:15:52 +0000
Subject: [PATCH 2/3] format

---
 .../include/sanitizer/tsan_interface.h        |   2 +-
 .../include/sanitizer/tysan_interface.h       |  26 +--
 compiler-rt/lib/tysan/tysan.cpp               |  14 +-
 compiler-rt/lib/tysan/tysan_interface.cpp     |  31 ++--
 compiler-rt/lib/tysan/tysan_interface.h       |   7 +-
 .../test/tysan/interface-manipulate-shadow.c  | 154 +++++++++---------
 compiler-rt/test/tysan/interface-print-type.c |  40 ++---
 7 files changed, 143 insertions(+), 131 deletions(-)

diff --git a/compiler-rt/include/sanitizer/tsan_interface.h b/compiler-rt/include/sanitizer/tsan_interface.h
index e11a4175cd8ed..98fac85fd907a 100644
--- a/compiler-rt/include/sanitizer/tsan_interface.h
+++ b/compiler-rt/include/sanitizer/tsan_interface.h
@@ -1,4 +1,4 @@
-//===-- tsan_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.
diff --git a/compiler-rt/include/sanitizer/tysan_interface.h b/compiler-rt/include/sanitizer/tysan_interface.h
index 8cb35ae4b5c09..d198363df3a34 100644
--- a/compiler-rt/include/sanitizer/tysan_interface.h
+++ b/compiler-rt/include/sanitizer/tysan_interface.h
@@ -1,4 +1,4 @@
-//===-- tsan_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.
@@ -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 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 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 fdffe784d0c74..b234dbf272c6e 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -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 c2da6246b0044..3d7d9d101c5f9 100644
--- a/compiler-rt/lib/tysan/tysan_interface.cpp
+++ b/compiler-rt/lib/tysan/tysan_interface.cpp
@@ -1,4 +1,4 @@
-//===-- tysan_interface.inc --------------------------------------*- C++ -*-===//
+//===-- tysan_interface.cpp -------------------------------------*- 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 +9,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 5a5e5cc08d2b3..9af0c66f0b606 100644
--- a/compiler-rt/lib/tysan/tysan_interface.h
+++ b/compiler-rt/lib/tysan/tysan_interface.h
@@ -1,4 +1,4 @@
-//===-- 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 +27,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 +37,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 504de2876cf26..25614e25e1f6c 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 c61a7dc477353..18c3bb0ceab20 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;
 }

>From 26c481fbbd8fe9a803f2822bda743d90cd23dea5 Mon Sep 17 00:00:00 2001
From: gbMattN <matthew.nagy at sony.com>
Date: Fri, 21 Nov 2025 11:16:44 +0000
Subject: [PATCH 3/3] remove typo

---
 compiler-rt/include/sanitizer/tsan_interface.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/include/sanitizer/tsan_interface.h b/compiler-rt/include/sanitizer/tsan_interface.h
index 98fac85fd907a..e11a4175cd8ed 100644
--- a/compiler-rt/include/sanitizer/tsan_interface.h
+++ b/compiler-rt/include/sanitizer/tsan_interface.h
@@ -1,4 +1,4 @@
-//===-- tysan_interface.h ---------------------------------------*- C++ -*-===//
+//===-- tsan_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.



More information about the llvm-commits mailing list