xref: /aosp_15_r20/external/compiler-rt/test/msan/dtor-bit-fields.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
2*7c3d14c8STreehugger Robot 
3*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
4*7c3d14c8STreehugger Robot 
5*7c3d14c8STreehugger Robot // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
6*7c3d14c8STreehugger Robot 
7*7c3d14c8STreehugger Robot #include <sanitizer/msan_interface.h>
8*7c3d14c8STreehugger Robot #include <assert.h>
9*7c3d14c8STreehugger Robot 
10*7c3d14c8STreehugger Robot // TODO: remove empty dtors when msan use-after-dtor poisons
11*7c3d14c8STreehugger Robot // for trivial classes with undeclared dtors
12*7c3d14c8STreehugger Robot 
13*7c3d14c8STreehugger Robot // 24 bytes total
14*7c3d14c8STreehugger Robot struct Packed {
15*7c3d14c8STreehugger Robot   // Packed into 4 bytes
16*7c3d14c8STreehugger Robot   unsigned int a : 1;
17*7c3d14c8STreehugger Robot   unsigned int b : 1;
18*7c3d14c8STreehugger Robot   // Force alignment to next 4 bytes
19*7c3d14c8STreehugger Robot   unsigned int   : 0;
20*7c3d14c8STreehugger Robot   unsigned int c : 1;
21*7c3d14c8STreehugger Robot   // Force alignment, 8 more bytes
22*7c3d14c8STreehugger Robot   double d = 5.0;
23*7c3d14c8STreehugger Robot   // 4 bytes
24*7c3d14c8STreehugger Robot   unsigned int e : 1;
~PackedPacked25*7c3d14c8STreehugger Robot   ~Packed() {}
26*7c3d14c8STreehugger Robot };
27*7c3d14c8STreehugger Robot 
28*7c3d14c8STreehugger Robot // 1 byte total
29*7c3d14c8STreehugger Robot struct Empty {
30*7c3d14c8STreehugger Robot   unsigned int : 0;
~EmptyEmpty31*7c3d14c8STreehugger Robot   ~Empty() {}
32*7c3d14c8STreehugger Robot };
33*7c3d14c8STreehugger Robot 
34*7c3d14c8STreehugger Robot // 4 byte total
35*7c3d14c8STreehugger Robot struct Simple {
36*7c3d14c8STreehugger Robot   unsigned int a : 1;
~SimpleSimple37*7c3d14c8STreehugger Robot   ~Simple() {}
38*7c3d14c8STreehugger Robot };
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot struct Anon {
41*7c3d14c8STreehugger Robot   unsigned int a : 1;
42*7c3d14c8STreehugger Robot   unsigned int b : 2;
43*7c3d14c8STreehugger Robot   unsigned int   : 0;
44*7c3d14c8STreehugger Robot   unsigned int c : 1;
~AnonAnon45*7c3d14c8STreehugger Robot   ~Anon() {}
46*7c3d14c8STreehugger Robot };
47*7c3d14c8STreehugger Robot 
main()48*7c3d14c8STreehugger Robot int main() {
49*7c3d14c8STreehugger Robot   Packed *p = new Packed();
50*7c3d14c8STreehugger Robot   p->~Packed();
51*7c3d14c8STreehugger Robot   for (int i = 0; i < 4; i++)
52*7c3d14c8STreehugger Robot     assert(__msan_test_shadow(((char*)p) + i, sizeof(char)) != -1);
53*7c3d14c8STreehugger Robot   assert(__msan_test_shadow(&p->d, sizeof(double)) != -1);
54*7c3d14c8STreehugger Robot   assert(__msan_test_shadow(((char*)(&p->d)) + sizeof(double), sizeof(char)) !=
55*7c3d14c8STreehugger Robot          -1);
56*7c3d14c8STreehugger Robot 
57*7c3d14c8STreehugger Robot   Empty *e = new Empty();
58*7c3d14c8STreehugger Robot   e->~Empty();
59*7c3d14c8STreehugger Robot   assert(__msan_test_shadow(e, sizeof(*e)) != -1);
60*7c3d14c8STreehugger Robot 
61*7c3d14c8STreehugger Robot   Simple *s = new Simple();
62*7c3d14c8STreehugger Robot   s->~Simple();
63*7c3d14c8STreehugger Robot   assert(__msan_test_shadow(s, sizeof(*s)) != -1);
64*7c3d14c8STreehugger Robot 
65*7c3d14c8STreehugger Robot   Anon *a = new Anon();
66*7c3d14c8STreehugger Robot   a->~Anon();
67*7c3d14c8STreehugger Robot   assert(__msan_test_shadow(a, sizeof(*a)) != -1);
68*7c3d14c8STreehugger Robot 
69*7c3d14c8STreehugger Robot   return 0;
70*7c3d14c8STreehugger Robot }
71