[NFC][CodeGen] Add sanitize-dtor-zero-size-field test
authorVitaly Buka <vitalybuka@google.com>
Sat, 5 Dec 2020 08:54:14 +0000 (00:54 -0800)
committerVitaly Buka <vitalybuka@google.com>
Sun, 6 Dec 2020 00:39:48 +0000 (16:39 -0800)
The test demonstrates invalid behaviour which will be fixed soon.

clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp [new file with mode: 0644]

diff --git a/clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp b/clang/test/CodeGenCXX/sanitize-dtor-zero-size-field.cpp
new file mode 100644 (file)
index 0000000..e876f93
--- /dev/null
@@ -0,0 +1,378 @@
+// RUN: %clang_cc1 -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 -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"
+
+// This test convers invalid behaviour which will be fixed in followup patches.
+
+struct Empty {};
+
+struct EmptyNonTrivial {
+  ~EmptyNonTrivial();
+};
+
+struct Trivial {
+  int a;
+  char c;
+};
+static_assert(sizeof(Trivial) == 8);
+
+struct NonTrivial {
+  int a;
+  char c;
+  ~NonTrivial();
+};
+static_assert(sizeof(NonTrivial) == 8);
+
+namespace T0 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  ~Struct(){};
+} var;
+static_assert(sizeof(Struct) == 16);
+} // namespace T0
+// CHECK-LABEL: define {{.*}} @_ZN2T06StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace empty {
+namespace T1 {
+struct Struct {
+  NonTrivial nt;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T1
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T16StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace T2 {
+struct Struct {
+  Trivial f1;
+  NonTrivial nt;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T2
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T26StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK-NEXT:    ret void
+
+namespace T3 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  NonTrivial nt;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T3
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T36StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK-NEXT:    ret void
+
+namespace T4 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  NonTrivial nt;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T4
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T46StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK-NEXT:    ret void
+
+namespace T5 {
+struct Struct {
+  [[no_unique_address]] Empty e;
+  NonTrivial nt;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T5
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T56StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace T6 {
+struct Struct {
+  NonTrivial nt;
+  [[no_unique_address]] Empty e;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T6
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T66StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 21)
+// CHECK-NEXT:    ret void
+
+namespace T7 {
+struct Struct {
+  Trivial f1;
+  NonTrivial nt;
+  [[no_unique_address]] Empty e;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T7
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T76StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 21)
+// CHECK-NEXT:    ret void
+
+namespace T8 {
+struct Struct {
+  Trivial f1;
+  [[no_unique_address]] Empty e;
+  NonTrivial nt;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T8
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T86StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK-NEXT:    ret void
+
+namespace T9 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  NonTrivial nt;
+  [[no_unique_address]] Empty e;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T9
+// CHECK-LABEL: define {{.*}} @_ZN5empty2T96StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 21)
+// CHECK-NEXT:    ret void
+
+namespace T10 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  [[no_unique_address]] Empty e;
+  NonTrivial nt;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T10
+// CHECK-LABEL: define {{.*}} @_ZN5empty3T106StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK-NEXT:    ret void
+
+namespace T11 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  NonTrivial nt;
+  [[no_unique_address]] Empty e;
+} var;
+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(i8* {{.*}}, i64 24)
+// CHECK-NEXT:    ret void
+
+namespace T12 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  [[no_unique_address]] Empty e;
+  NonTrivial nt;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T12
+} // namespace empty
+// CHECK-LABEL: define {{.*}} @_ZN5empty3T126StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK-NEXT:    ret void
+
+namespace empty_non_trivial {
+namespace T1 {
+struct Struct {
+  NonTrivial nt;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T1
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T16StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace T2 {
+struct Struct {
+  Trivial f1;
+  NonTrivial nt;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T2
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T26StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK-NEXT:    ret void
+
+namespace T3 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  NonTrivial nt;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T3
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T36StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK-NEXT:    ret void
+
+namespace T4 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  NonTrivial nt;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T4
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T46StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK-NEXT:    ret void
+
+namespace T5 {
+struct Struct {
+  [[no_unique_address]] EmptyNonTrivial e;
+  NonTrivial nt;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T5
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T56StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace T6 {
+struct Struct {
+  NonTrivial nt;
+  [[no_unique_address]] EmptyNonTrivial e;
+  Trivial f1;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T6
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T66StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 13)
+// CHECK-NEXT:    ret void
+
+namespace T7 {
+struct Struct {
+  Trivial f1;
+  NonTrivial nt;
+  [[no_unique_address]] EmptyNonTrivial e;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T7
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T76StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 8)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK-NEXT:    ret void
+
+namespace T8 {
+struct Struct {
+  Trivial f1;
+  [[no_unique_address]] EmptyNonTrivial e;
+  NonTrivial nt;
+  int f2;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T8
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T86StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 5)
+// CHECK-NEXT:    ret void
+
+namespace T9 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  NonTrivial nt;
+  [[no_unique_address]] EmptyNonTrivial e;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T9
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial2T96StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 12)
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK-NEXT:    ret void
+
+namespace T10 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  [[no_unique_address]] EmptyNonTrivial e;
+  NonTrivial nt;
+  char f3;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T10
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T106StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 1)
+// CHECK-NEXT:    ret void
+
+namespace T11 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  NonTrivial nt;
+  [[no_unique_address]] EmptyNonTrivial e;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T11
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T116StructD2Ev(
+// CHECK:         call void @__sanitizer_dtor_callback(i8* {{.*}}, i64 16)
+// CHECK-NEXT:    ret void
+
+namespace T12 {
+struct Struct {
+  Trivial f1;
+  int f2;
+  char f3;
+  [[no_unique_address]] EmptyNonTrivial e;
+  NonTrivial nt;
+} var;
+static_assert(sizeof(Struct) == 24);
+} // namespace T12
+} // namespace empty_non_trivial
+// CHECK-LABEL: define {{.*}} @_ZN17empty_non_trivial3T126StructD2Ev(
+// CHECK:         ret void