summaryrefslogtreecommitdiff
path: root/test/msan/dtor-bit-fields.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/msan/dtor-bit-fields.cc')
-rw-r--r--test/msan/dtor-bit-fields.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/test/msan/dtor-bit-fields.cc b/test/msan/dtor-bit-fields.cc
new file mode 100644
index 0000000000000..4c6e322e63639
--- /dev/null
+++ b/test/msan/dtor-bit-fields.cc
@@ -0,0 +1,70 @@
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+
+// TODO: remove empty dtors when msan use-after-dtor poisons
+// for trivial classes with undeclared dtors
+
+// 24 bytes total
+struct Packed {
+ // Packed into 4 bytes
+ unsigned int a : 1;
+ unsigned int b : 1;
+ // Force alignment to next 4 bytes
+ unsigned int : 0;
+ unsigned int c : 1;
+ // Force alignment, 8 more bytes
+ double d = 5.0;
+ // 4 bytes
+ unsigned int e : 1;
+ ~Packed() {}
+};
+
+// 1 byte total
+struct Empty {
+ unsigned int : 0;
+ ~Empty() {}
+};
+
+// 4 byte total
+struct Simple {
+ unsigned int a : 1;
+ ~Simple() {}
+};
+
+struct Anon {
+ unsigned int a : 1;
+ unsigned int b : 2;
+ unsigned int : 0;
+ unsigned int c : 1;
+ ~Anon() {}
+};
+
+int main() {
+ Packed *p = new Packed();
+ p->~Packed();
+ for (int i = 0; i < 4; i++)
+ assert(__msan_test_shadow(((char*)p) + i, sizeof(char)) != -1);
+ assert(__msan_test_shadow(&p->d, sizeof(double)) != -1);
+ assert(__msan_test_shadow(((char*)(&p->d)) + sizeof(double), sizeof(char)) !=
+ -1);
+
+ Empty *e = new Empty();
+ e->~Empty();
+ assert(__msan_test_shadow(e, sizeof(*e)) != -1);
+
+ Simple *s = new Simple();
+ s->~Simple();
+ assert(__msan_test_shadow(s, sizeof(*s)) != -1);
+
+ Anon *a = new Anon();
+ a->~Anon();
+ assert(__msan_test_shadow(a, sizeof(*a)) != -1);
+
+ return 0;
+}