dtor-bit-fields.cpp
1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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;
}