1*eb4d2291SVitaly Buka // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1 2*eb4d2291SVitaly Buka // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1 3*eb4d2291SVitaly Buka // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&1 4d21b3d34SFangrui Song 5d21b3d34SFangrui Song #include <sanitizer/msan_interface.h> 6d21b3d34SFangrui Song #include <assert.h> 7d21b3d34SFangrui Song 8d21b3d34SFangrui Song struct Base { 9d21b3d34SFangrui Song int x; BaseBase10d21b3d34SFangrui Song Base() { x = 5; } ~BaseBase11d21b3d34SFangrui Song virtual ~Base() {} 12d21b3d34SFangrui Song }; 13d21b3d34SFangrui Song 14d21b3d34SFangrui Song struct Derived : public Base { 15d21b3d34SFangrui Song int y; DerivedDerived16d21b3d34SFangrui Song Derived() { y = 10; } ~DerivedDerived17d21b3d34SFangrui Song ~Derived() {} 18d21b3d34SFangrui Song }; 19d21b3d34SFangrui Song main()20d21b3d34SFangrui Songint main() { 21d21b3d34SFangrui Song Derived *d = new Derived(); 22d21b3d34SFangrui Song d->~Derived(); 23d21b3d34SFangrui Song 24d21b3d34SFangrui Song // Verify that local pointer is unpoisoned, and that the object's 25d21b3d34SFangrui Song // members are. 26d21b3d34SFangrui Song assert(__msan_test_shadow(&d, sizeof(d)) == -1); 27d21b3d34SFangrui Song assert(__msan_test_shadow(&d->x, sizeof(d->x)) != -1); 28d21b3d34SFangrui Song assert(__msan_test_shadow(&d->y, sizeof(d->y)) != -1); 29d21b3d34SFangrui Song 30d21b3d34SFangrui Song Base *b = new Derived(); 31d21b3d34SFangrui Song b->~Base(); 32d21b3d34SFangrui Song 33d21b3d34SFangrui Song // Verify that local pointer is unpoisoned, and that the object's 34d21b3d34SFangrui Song // members are. 35d21b3d34SFangrui Song assert(__msan_test_shadow(&b, sizeof(b)) == -1); 36d21b3d34SFangrui Song assert(__msan_test_shadow(&b->x, sizeof(b->x)) != -1); 37d21b3d34SFangrui Song 38d21b3d34SFangrui Song return 0; 39d21b3d34SFangrui Song } 40