vitalybuka created this revision.
Herald added a subscriber: Enna1.
Herald added a project: All.
vitalybuka requested review of this revision.
Herald added projects: clang, Sanitizers.
Herald added subscribers: Sanitizers, cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132907

Files:
  clang/lib/CodeGen/CGClass.cpp
  clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
  clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
  clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
  clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp
  clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
  clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp
  compiler-rt/include/sanitizer/msan_interface.h
  compiler-rt/lib/msan/msan.h
  compiler-rt/lib/msan/msan_interceptors.cpp
  compiler-rt/lib/msan/msan_interface_internal.h
  compiler-rt/lib/msan/msan_report.cpp
  compiler-rt/test/msan/dtor-base-access.cpp
  compiler-rt/test/msan/dtor-vtable-multiple-inheritance.cpp
  compiler-rt/test/msan/use-after-dtor.cpp

Index: compiler-rt/test/msan/use-after-dtor.cpp
===================================================================
--- compiler-rt/test/msan/use-after-dtor.cpp
+++ compiler-rt/test/msan/use-after-dtor.cpp
@@ -32,7 +32,7 @@
   // CHECK-UAD: WARNING: MemorySanitizer: use-of-uninitialized-value
   // CHECK-UAD: {{#0 0x.* in main.*use-after-dtor.cpp:}}[[@LINE-3]]
 
-  // CHECK-ORIGINS: Memory was marked as uninitialized
+  // CHECK-ORIGINS: Member fields were destroyed
   // CHECK-ORIGINS: {{#0 0x.* in __sanitizer_dtor_callback}}
   // CHECK-ORIGINS: {{#1 0x.* in .*~Simple.*cpp:}}[[@LINE-18]]:
 
Index: compiler-rt/test/msan/dtor-vtable-multiple-inheritance.cpp
===================================================================
--- compiler-rt/test/msan/dtor-vtable-multiple-inheritance.cpp
+++ compiler-rt/test/msan/dtor-vtable-multiple-inheritance.cpp
@@ -51,8 +51,8 @@
   // This fails
 #ifdef CVPTR
   c->A_Foo();
-// CVPTR: Memory was marked as uninitialized
-// CVPTR: {{#0 0x.* in __sanitizer_dtor_callback}}
+// CVPTR: Virtual table ptr was destroyed
+// CVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}}
 // CVPTR: {{#1 0x.* in ~C .*cpp:}}[[@LINE-28]]:
 // CVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-7]]:
 #endif
@@ -63,16 +63,16 @@
   // Both of these fail
 #ifdef EAVPTR
   e->A_Foo();
-// EAVPTR: Memory was marked as uninitialized
-// EAVPTR: {{#0 0x.* in __sanitizer_dtor_callback}}
+// EAVPTR: Virtual table ptr was destroyed
+// EAVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}}
 // EAVPTR: {{#1 0x.* in ~E .*cpp:}}[[@LINE-25]]:
 // EAVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-7]]:
 #endif
 
 #ifdef EDVPTR
   e->D_Foo();
-// EDVPTR: Memory was marked as uninitialized
-// EDVPTR: {{#0 0x.* in __sanitizer_dtor_callback}}
+// EDVPTR: Virtual table ptr was destroyed
+// EDVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}}
 // EDVPTR: {{#1 0x.* in ~E .*cpp:}}[[@LINE-33]]:
 // EDVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-15]]:
 #endif
Index: compiler-rt/test/msan/dtor-base-access.cpp
===================================================================
--- compiler-rt/test/msan/dtor-base-access.cpp
+++ compiler-rt/test/msan/dtor-base-access.cpp
@@ -66,17 +66,17 @@
   assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);
 
   __msan_print_shadow(&g->tb0, sizeof(g->tb0));
-  // CHECK: Memory was marked as uninitialized
+  // CHECK: Member fields were destroyed
   // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
   // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-20]]:
 
   __msan_print_shadow(&g->b, sizeof(g->b));
-  // CHECK: Memory was marked as uninitialized
+  // CHECK: Member fields were destroyed
   // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
   // CHECK: {{#1 0x.* in .*~Base.*cpp:}}[[@LINE-33]]:
 
   __msan_print_shadow(&g->tb1, sizeof(g->tb1));
-  // CHECK: Memory was marked as uninitialized
+  // CHECK: Member fields were destroyed
   // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
   // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-30]]:
 
Index: compiler-rt/lib/msan/msan_report.cpp
===================================================================
--- compiler-rt/lib/msan/msan_report.cpp
+++ compiler-rt/lib/msan/msan_report.cpp
@@ -81,6 +81,13 @@
         Printf("  %sMemory was marked as uninitialized%s\n", d.Origin(),
                d.Default());
         break;
+      case STACK_TRACE_TAG_FIELDS:
+        Printf("  %sMember fields were destroyed%s\n", d.Origin(), d.Default());
+        break;
+      case STACK_TRACE_TAG_VPTR:
+        Printf("  %sVirtual table ptr was destroyed%s\n", d.Origin(),
+               d.Default());
+        break;
       default:
         Printf("  %sUninitialized value was created%s\n", d.Origin(),
                d.Default());
Index: compiler-rt/lib/msan/msan_interface_internal.h
===================================================================
--- compiler-rt/lib/msan/msan_interface_internal.h
+++ compiler-rt/lib/msan/msan_interface_internal.h
@@ -162,6 +162,10 @@
 // uninitialized.
 SANITIZER_INTERFACE_ATTRIBUTE
 void __sanitizer_dtor_callback(const void* data, uptr size);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_dtor_callback_fields(const void *data, uptr size);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_dtor_callback_vptr(const void *data);
 
 SANITIZER_INTERFACE_ATTRIBUTE
 u16 __sanitizer_unaligned_load16(const uu16 *p);
Index: compiler-rt/lib/msan/msan_interceptors.cpp
===================================================================
--- compiler-rt/lib/msan/msan_interceptors.cpp
+++ compiler-rt/lib/msan/msan_interceptors.cpp
@@ -944,6 +944,22 @@
   }
 }
 
+void __sanitizer_dtor_callback_fields(const void *data, uptr size) {
+  if (flags()->poison_in_dtor) {
+    GET_MALLOC_STACK_TRACE;
+    stack.tag = STACK_TRACE_TAG_FIELDS;
+    PoisonMemory(data, size, &stack);
+  }
+}
+
+void __sanitizer_dtor_callback_vptr(const void *data) {
+  if (flags()->poison_in_dtor) {
+    GET_MALLOC_STACK_TRACE;
+    stack.tag = STACK_TRACE_TAG_VPTR;
+    PoisonMemory(data, sizeof(void *), &stack);
+  }
+}
+
 template <class Mmap>
 static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
                               int prot, int flags, int fd, OFF64_T offset) {
Index: compiler-rt/lib/msan/msan.h
===================================================================
--- compiler-rt/lib/msan/msan.h
+++ compiler-rt/lib/msan/msan.h
@@ -349,6 +349,8 @@
 u32 ChainOrigin(u32 id, StackTrace *stack);
 
 const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
+const int STACK_TRACE_TAG_FIELDS = STACK_TRACE_TAG_POISON + 1;
+const int STACK_TRACE_TAG_VPTR = STACK_TRACE_TAG_FIELDS + 1;
 
 #define GET_MALLOC_STACK_TRACE                                            \
   BufferedStackTrace stack;                                               \
Index: compiler-rt/include/sanitizer/msan_interface.h
===================================================================
--- compiler-rt/include/sanitizer/msan_interface.h
+++ compiler-rt/include/sanitizer/msan_interface.h
@@ -92,6 +92,8 @@
 
   /* Tell MSan about newly destroyed memory. Mark memory as uninitialized. */
   void __sanitizer_dtor_callback(const volatile void* data, size_t size);
+  void __sanitizer_dtor_callback_fields(const volatile void *data, size_t size);
+  void __sanitizer_dtor_callback_vptr(const volatile void *data);
 
   /* This function may be optionally provided by user and should return
      a string containing Msan runtime options. See msan_flags.h for details. */
Index: clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback"
-// RUN: %clang_cc1 -no-opaque-pointers -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback"
+// RUN: %clang_cc1 -no-opaque-pointers -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback_fields"
+// RUN: %clang_cc1 -no-opaque-pointers -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++20 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s --implicit-check-not "call void @__sanitizer_dtor_callback_fields"
 
 struct Empty {};
 
@@ -30,7 +30,7 @@
 static_assert(sizeof(Struct) == 16);
 } // namespace T0
 // CHECK-LABEL: define {{.*}} @_ZN2T06StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK-NEXT:    ret void
 
 namespace empty {
@@ -45,7 +45,7 @@
 } // namespace T1
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T16StructD2Ev(
 // CHECK:         [[GEP:%.+]] = getelementptr i8, {{.*}}, i64 8{{$}}
-// CHECK:         call void @__sanitizer_dtor_callback(i8* [[GEP]], i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* [[GEP]], i64 13)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -60,10 +60,10 @@
 } // namespace T2
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T26StructD2Ev(
 // CHECK:         [[GEP1:%.+]] = getelementptr i8, {{.*}}, i64 16{{$}}
-// CHECK:         call void @__sanitizer_dtor_callback(i8* [[GEP1]], i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* [[GEP1]], i64 5)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK:         [[GEP2:%.+]] = getelementptr i8, {{.*}}, i64 0{{$}}
-// CHECK:         call void @__sanitizer_dtor_callback(i8* [[GEP2]], i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* [[GEP2]], i64 8)
 // CHECK-NEXT:    ret void
 
 namespace T3 {
@@ -77,10 +77,10 @@
 } // namespace T3
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T36StructD2Ev(
 // CHECK:         [[GEP1:%.+]] = getelementptr i8, {{.*}}, i64 20{{$}}
-// CHECK:         call void @__sanitizer_dtor_callback(i8* [[GEP1]], i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* [[GEP1]], i64 1)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK:         [[GEP2:%.+]] = getelementptr i8, {{.*}}, i64 0{{$}}
-// CHECK:         call void @__sanitizer_dtor_callback(i8* [[GEP2]], i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* [[GEP2]], i64 12)
 // CHECK-NEXT:    ret void
 
 namespace T4 {
@@ -93,7 +93,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T4
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T46StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK-NEXT:    ret void
 
 namespace T5 {
@@ -107,7 +107,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T5
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T56StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -122,7 +122,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T6
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T66StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -137,9 +137,9 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T7
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T76StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 5)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 8)
 // CHECK-NEXT:    ret void
 
 namespace T8 {
@@ -153,8 +153,8 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T8
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T86StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 8)
 // CHECK-NEXT:    ret void
 
 namespace T9 {
@@ -168,8 +168,8 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T9
 // CHECK-LABEL: define {{.*}} @_ZN5empty2T96StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 12)
 // CHECK-NEXT:    ret void
 
 namespace T10 {
@@ -183,8 +183,8 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T10
 // CHECK-LABEL: define {{.*}} @_ZN5empty3T106StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 12)
 // CHECK-NEXT:    ret void
 
 namespace T11 {
@@ -198,7 +198,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T11
 // CHECK-LABEL: define {{.*}} @_ZN5empty3T116StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK-NEXT:    ret void
 
 namespace T12 {
@@ -214,7 +214,7 @@
 } // namespace empty
 // CHECK-LABEL: define {{.*}} @_ZN5empty3T126StructD2Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK-NEXT:    ret void
 
 namespace empty_non_trivial {
@@ -228,7 +228,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T1
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T16StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -242,8 +242,8 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T2
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T26StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 8)
 // CHECK-NEXT:    ret void
 
 namespace T3 {
@@ -256,8 +256,8 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T3
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T36StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 12)
 // CHECK-NEXT:    ret void
 
 namespace T4 {
@@ -270,7 +270,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T4
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T46StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK-NEXT:    ret void
 
 namespace T5 {
@@ -284,7 +284,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T5
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T56StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK-NEXT:    ret void
@@ -300,7 +300,7 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T6
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T66StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 13)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
 // CHECK-NEXT:    ret void
@@ -316,10 +316,10 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T7
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T76StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 5)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 8)
 // CHECK-NEXT:    ret void
 
 namespace T8 {
@@ -333,9 +333,9 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T8
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T86StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 5)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 8)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -350,10 +350,10 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T9
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T96StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 1)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 12)
 // CHECK-NEXT:    ret void
 
 namespace T10 {
@@ -367,9 +367,9 @@
 static_assert(sizeof(Struct) == 24);
 } // namespace T10
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T106StructD2Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 1)
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 12)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK-NEXT:    ret void
 
@@ -386,7 +386,7 @@
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T116StructD2Ev(
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK-NEXT:    ret void
 
 namespace T12 {
@@ -402,6 +402,6 @@
 } // namespace empty_non_trivial
 // CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T126StructD2Ev(
 // CHECK:         call void @_ZN10NonTrivialD1Ev(
-// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK:         call void @__sanitizer_dtor_callback_fields(i8* {{.*}}, i64 16)
 // CHECK:         call void @_ZN15EmptyNonTrivialD1Ev(
 // CHECK:         ret void
Index: clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -25,18 +25,18 @@
 // CHECK-LABEL: define {{.*}}BD1Ev
 // CHECK: call void {{.*}}BD2Ev
 // CHECK: call void {{.*}}AD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI1:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}, !dbg ![[DI1:[0-9]+]]
 // CHECK: ret void
 
 // Since no virtual bases, poison vtable ptr here.
 // CHECK-LABEL: define {{.*}}AD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI2:[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI2]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI2:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}, !dbg ![[DI2]]
 // CHECK: ret void
 
 // Poison members
 // CHECK-LABEL: define {{.*}}BD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI4:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI4:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}cpp
Index: clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp
@@ -20,8 +20,8 @@
 // Poison members, then poison the trivial base class.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: %[[GEP:[0-9a-z]+]] = getelementptr i8, i8* {{.*}}, i64 16
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}%[[GEP]], i64 4{{.*}}, !dbg ![[DI:[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 16{{.*}}, !dbg ![[DI]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}%[[GEP]], i64 4{{.*}}, !dbg ![[DI:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16{{.*}}, !dbg ![[DI]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}cpp
Index: clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
@@ -15,7 +15,7 @@
 Simple s;
 // Simple internal member is poisoned by compiler-generated dtor
 // CHECK: define {{.*}}SimpleD2Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
-// CHECK: {{^ *}}call void @__sanitizer_dtor_callback(
+// CHECK: call void @__sanitizer_dtor_callback_fields(
 // CHECK: ret void
 
 // Destructor does not emit any tail calls
Index: clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -47,7 +47,7 @@
 
 // CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
 // CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}){{.*}}, !dbg ![[DI0:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI0:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
@@ -61,27 +61,27 @@
 
 // poison 2 ints
 // CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 8){{.*}}, !dbg ![[DI1:[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 8){{.*}}, !dbg ![[DI1:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI1]]
 // CHECK: ret void
 
 // poison int and double
 // CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}{{.*}}, !dbg ![[DI2:[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16){{.*}}, !dbg ![[DI2:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}{{.*}}, !dbg ![[DI2]]
 // CHECK: ret void
 
 // poison int, ignore vector, poison int
 // CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 4){{.*}}, !dbg ![[DI3:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI3:[0-9]+]]
 // CHECK: call void {{.*}}ZN6VectorIiED1Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 4){{.*}}, !dbg ![[DI3]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI3]]
 // CHECK: call void {{.*}}ZN4BaseD2Ev
 // CHECK: ret void
 
 // poison int
 // CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, i64 4){{.*}}, !dbg ![[DI5:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI5:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}.cpp
Index: clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -49,15 +49,15 @@
 
 // Poison members and vtable ptr.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI1:[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 8{{.*}}, !dbg ![[DI1]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI1:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI1]]
 // CHECK: ret void
 
 // Poison members and destroy non-virtual base.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI3:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI3:[0-9]+]]
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 8{{.*}}, !dbg ![[DI3]]
+// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI3]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}cpp
Index: clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
@@ -56,16 +56,16 @@
 // instrumentation inserted.
 // CHECK-LABEL: define {{.*}}SimpleD2Ev
 // CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI1:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI1:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}InlinedD2Ev
 // CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI2:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI2:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}, !dbg ![[DI3:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI3:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}cpp
Index: clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
===================================================================
--- clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
+++ clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -63,22 +63,22 @@
 Adjacent ad;
 
 // CHECK-LABEL: define {{.*}}PackedD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 17{{.*}}, !dbg ![[DI1:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}i64 17{{.*}}, !dbg ![[DI1:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}EmptyD2Ev
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}SimpleD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 1{{.*}}, !dbg ![[DI2:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}i64 1{{.*}}, !dbg ![[DI2:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}AnonD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 5{{.*}}, !dbg ![[DI3:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}i64 5{{.*}}, !dbg ![[DI3:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: define {{.*}}AdjacentD2Ev
-// CHECK: call void @__sanitizer_dtor_callback({{.*}}i64 1{{.*}}, !dbg ![[DI4:[0-9]+]]
+// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}i64 1{{.*}}, !dbg ![[DI4:[0-9]+]]
 // CHECK: ret void
 
 // CHECK-LABEL: !DIFile{{.*}}cpp
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -1649,23 +1649,35 @@
     }
   };
 
-  static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
-                                        CharUnits::QuantityType PoisonSize) {
+  static void EmitSanitizerDtorCallback(
+      CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr,
+      llvm::Optional<CharUnits::QuantityType> PoisonSize = {}) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     // Pass in void pointer and size of region as arguments to runtime
     // function
-    llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
-                           llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+    SmallVector<llvm::Value *, 2> Args = {
+        CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy)};
+    SmallVector<llvm::Type *, 2> ArgTypes = {CGF.VoidPtrTy};
 
-    llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+    if (PoisonSize.has_value()) {
+      Args.emplace_back(llvm::ConstantInt::get(CGF.SizeTy, *PoisonSize));
+      ArgTypes.emplace_back(CGF.SizeTy);
+    }
 
     llvm::FunctionType *FnType =
         llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
-    llvm::FunctionCallee Fn =
-        CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+    llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FnType, Name);
+
     CGF.EmitNounwindRuntimeCall(Fn, Args);
   }
 
+  static void
+  EmitSanitizerDtorFieldsCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+                                  CharUnits::QuantityType PoisonSize) {
+    EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_fields", Ptr,
+                              PoisonSize);
+  }
+
   /// Poison base class with a trivial destructor.
   struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
     const CXXRecordDecl *BaseClass;
@@ -1687,7 +1699,8 @@
       if (!BaseSize.isPositive())
         return;
 
-      EmitSanitizerDtorCallback(CGF, Addr.getPointer(), BaseSize.getQuantity());
+      EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(),
+                                      BaseSize.getQuantity());
 
       // Prevent the current stack frame from disappearing from the stack trace.
       CGF.CurFn->addFnAttr("disable-tail-calls", "true");
@@ -1735,7 +1748,7 @@
       if (!PoisonSize.isPositive())
         return;
 
-      EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
+      EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
 
       // Prevent the current stack frame from disappearing from the stack trace.
       CGF.CurFn->addFnAttr("disable-tail-calls", "true");
@@ -1752,15 +1765,13 @@
     void Emit(CodeGenFunction &CGF, Flags flags) override {
       assert(Dtor->getParent()->isDynamicClass());
       (void)Dtor;
-      ASTContext &Context = CGF.getContext();
       // Poison vtable and vtable ptr if they exist for this class.
       llvm::Value *VTablePtr = CGF.LoadCXXThis();
 
-      CharUnits::QuantityType PoisonSize =
-          Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
       // Pass in void pointer and size of region as arguments to runtime
       // function
-      EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
+      EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_vptr",
+                                VTablePtr);
     }
  };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to