88 lines · cpp
1// RUN: %clangxx_msan %s -O0 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s2// RUN: %clangxx_msan %s -O1 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s3// RUN: %clangxx_msan %s -O2 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && %run %t 2>&1 | FileCheck %s4 5#include <sanitizer/msan_interface.h>6#include <assert.h>7 8class Base {9 public:10 int b;11 Base() { b = 1; }12 ~Base();13};14 15class TrivialBaseBefore {16public:17 int tb0;18 TrivialBaseBefore() { tb0 = 1; }19};20 21class TrivialBaseAfter {22public:23 int tb1;24 TrivialBaseAfter() { tb1 = 1; }25};26 27class Derived : public TrivialBaseBefore, public Base, public TrivialBaseAfter {28public:29 int d;30 Derived() { d = 1; }31 ~Derived();32};33 34Derived *g;35 36Base::~Base() {37 // ok to access its own members and earlier bases38 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);39 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);40 // not ok to access others41 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);42 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);43}44 45Derived::~Derived() {46 // ok to access everything47 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);48 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);49 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);50 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);51}52 53int main() {54 g = new Derived();55 // ok to access everything56 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == -1);57 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == -1);58 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == -1);59 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == -1);60 61 g->~Derived();62 // not ok to access everything63 assert(__msan_test_shadow(&g->tb0, sizeof(g->tb0)) == 0);64 assert(__msan_test_shadow(&g->b, sizeof(g->b)) == 0);65 assert(__msan_test_shadow(&g->tb1, sizeof(g->tb1)) == 0);66 assert(__msan_test_shadow(&g->d, sizeof(g->d)) == 0);67 68 __msan_print_shadow(&g->tb0, sizeof(g->tb0));69 // CHECK: Member fields were destroyed70 // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}71 // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-56]]:72 // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-21]]:73 74 __msan_print_shadow(&g->b, sizeof(g->b));75 // CHECK: Member fields were destroyed76 // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}77 // CHECK: {{#1 0x.* in .*~Base.*cpp:}}[[@LINE-67]]:78 // CHECK: {{#2 0x.* in .*~Base.*cpp:}}[[@LINE-35]]:79 80 __msan_print_shadow(&g->tb1, sizeof(g->tb1));81 // CHECK: Member fields were destroyed82 // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}}83 // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-62]]:84 // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-33]]:85 86 return 0;87}88