164dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O0 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s
264dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O1 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s
364dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O2 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s
4d21b3d34SFangrui Song
5d21b3d34SFangrui Song #include <sanitizer/msan_interface.h>
6d21b3d34SFangrui Song #include <assert.h>
7d21b3d34SFangrui Song
8d21b3d34SFangrui Song class Base {
9d21b3d34SFangrui Song public:
10c5ea8e91SEvgenii Stepanov int b;
Base()11c5ea8e91SEvgenii Stepanov Base() { b = 1; }
12c5ea8e91SEvgenii Stepanov ~Base();
13d21b3d34SFangrui Song };
14d21b3d34SFangrui Song
15c5ea8e91SEvgenii Stepanov class TrivialBaseBefore {
16d21b3d34SFangrui Song public:
17c5ea8e91SEvgenii Stepanov int tb0;
TrivialBaseBefore()18c5ea8e91SEvgenii Stepanov TrivialBaseBefore() { tb0 = 1; }
19c5ea8e91SEvgenii Stepanov };
20c5ea8e91SEvgenii Stepanov
21c5ea8e91SEvgenii Stepanov class TrivialBaseAfter {
22c5ea8e91SEvgenii Stepanov public:
23c5ea8e91SEvgenii Stepanov int tb1;
TrivialBaseAfter()24c5ea8e91SEvgenii Stepanov TrivialBaseAfter() { tb1 = 1; }
25c5ea8e91SEvgenii Stepanov };
26c5ea8e91SEvgenii Stepanov
27c5ea8e91SEvgenii Stepanov class Derived : public TrivialBaseBefore, public Base, public TrivialBaseAfter {
28c5ea8e91SEvgenii Stepanov public:
29c5ea8e91SEvgenii Stepanov int d;
Derived()30c5ea8e91SEvgenii Stepanov Derived() { d = 1; }
31d21b3d34SFangrui Song ~Derived();
32d21b3d34SFangrui Song };
33d21b3d34SFangrui Song
34c5ea8e91SEvgenii Stepanov Derived *g;
35c5ea8e91SEvgenii Stepanov
~Base()36d21b3d34SFangrui Song Base::~Base() {
37c5ea8e91SEvgenii Stepanov // ok to access its own members and earlier bases
38c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
39c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
40c5ea8e91SEvgenii Stepanov // not ok to access others
41c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);
42c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);
43d21b3d34SFangrui Song }
44d21b3d34SFangrui Song
~Derived()45d21b3d34SFangrui Song Derived::~Derived() {
46c5ea8e91SEvgenii Stepanov // ok to access everything
47c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
48c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
49c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);
50c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);
51d21b3d34SFangrui Song }
52d21b3d34SFangrui Song
main()53d21b3d34SFangrui Song int main() {
54c5ea8e91SEvgenii Stepanov g = new Derived();
55c5ea8e91SEvgenii Stepanov // ok to access everything
56c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);
57c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);
58c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);
59c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);
60c5ea8e91SEvgenii Stepanov
61c5ea8e91SEvgenii Stepanov g->~Derived();
62c5ea8e91SEvgenii Stepanov // not ok to access everything
63c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == 0);
64c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->b, sizeof(g->b)) == 0);
65c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);
66c5ea8e91SEvgenii Stepanov assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);
6764dbcca6SVitaly Buka
6864dbcca6SVitaly Buka __msan_print_shadow(&g->tb0, sizeof(g->tb0));
69c059ede2SVitaly Buka // CHECK: Member fields were destroyed
7064dbcca6SVitaly Buka // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
71*960e7a55SVitaly Buka // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-56]]:
72*960e7a55SVitaly Buka // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-21]]:
7364dbcca6SVitaly Buka
7464dbcca6SVitaly Buka __msan_print_shadow(&g->b, sizeof(g->b));
75c059ede2SVitaly Buka // CHECK: Member fields were destroyed
7664dbcca6SVitaly Buka // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
77*960e7a55SVitaly Buka // CHECK: {{#1 0x.* in .*~Base.*cpp:}}[[@LINE-67]]:
78*960e7a55SVitaly Buka // CHECK: {{#2 0x.* in .*~Base.*cpp:}}[[@LINE-35]]:
7964dbcca6SVitaly Buka
8064dbcca6SVitaly Buka __msan_print_shadow(&g->tb1, sizeof(g->tb1));
81c059ede2SVitaly Buka // CHECK: Member fields were destroyed
8264dbcca6SVitaly Buka // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}
83*960e7a55SVitaly Buka // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-62]]:
84*960e7a55SVitaly Buka // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-33]]:
8564dbcca6SVitaly Buka
86d21b3d34SFangrui Song return 0;
87d21b3d34SFangrui Song }
88