diff options
| author | Naomi Musgrave <nmusgrave@google.com> | 2015-09-03 23:02:30 +0000 |
|---|---|---|
| committer | Naomi Musgrave <nmusgrave@google.com> | 2015-09-03 23:02:30 +0000 |
| commit | 866af2d6d14292c255c50588e235c65a3b2406a3 (patch) | |
| tree | 09a704799c45d0248f463cfdd13e51ff49cb6cdc /clang/test | |
| parent | c285307e1457c4db2346443a4336e672d7487111 (diff) | |
| download | bcm5719-llvm-866af2d6d14292c255c50588e235c65a3b2406a3.tar.gz bcm5719-llvm-866af2d6d14292c255c50588e235c65a3b2406a3.zip | |
Refactored dtor sanitizing into EHScopeStack
Summary:
Dtor sanitization handled amidst other dtor cleanups,
between cleaning bases and fields. Sanitizer call pushed onto
stack of cleanup operations.
Reviewers: eugenis, kcc
Differential Revision: http://reviews.llvm.org/D12022
Refactoring dtor sanitizing emission order.
- Support multiple inheritance by poisoning after
member destructors are invoked, and before base
class destructors are invoked.
- Poison for virtual destructor and virtual bases.
- Repress dtor aliasing when sanitizing in dtor.
- CFE test for dtor aliasing, and repression of aliasing in dtor
code generation.
- Poison members on field-by-field basis, with collective poisoning
of trivial members when possible.
- Check msan flags and existence of fields, before dtor sanitizing,
and when determining if aliasing is allowed.
- Testing sanitizing bit fields.
llvm-svn: 246815
Diffstat (limited to 'clang/test')
3 files changed, 196 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp b/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp new file mode 100644 index 00000000000..d4497f6aac0 --- /dev/null +++ b/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp @@ -0,0 +1,84 @@ +// Test -fsanitize-memory-use-after-dtor +// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s + +// 24 bytes total +struct Packed { + // Packed into 4 bytes + unsigned int a : 1; + unsigned int b : 1; + //unsigned int c : 1; + // Force alignment to next 4 bytes + unsigned int : 0; + unsigned int d : 1; + // Force alignment, 8 more bytes + double e = 5.0; + // 4 bytes + unsigned int f : 1; + ~Packed() {} +}; +Packed p; + + +// 1 byte total +struct Empty { + unsigned int : 0; + ~Empty() {} +}; +Empty e; + + +// 4 byte total +struct Simple { + unsigned int a : 1; + ~Simple() {} +}; +Simple s; + + +// 8 bytes total +struct Anon { + // 1 byte + unsigned int a : 1; + unsigned int b : 2; + // Force alignment to next byte + unsigned int : 0; + unsigned int c : 1; + ~Anon() {} +}; +Anon an; + + +struct CharStruct { + char c; + ~CharStruct(); +}; + +struct Adjacent { + CharStruct a; + int b : 1; + CharStruct c; + ~Adjacent() {} +}; +Adjacent ad; + + +// CHECK-LABEL: define {{.*}}PackedD2Ev +// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 17 +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}EmptyD2Ev +// CHECK-NOT: call void @__sanitizer_dtor_callback{{.*}}i64 0 +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}SimpleD2Ev +// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 1 +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}AnonD2Ev +// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 5 +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}AdjacentD2Ev +// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 1 +// CHECK: ret void diff --git a/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp b/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp new file mode 100644 index 00000000000..27eb64b5534 --- /dev/null +++ b/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s + +template <class T> +class Vector { +public: + int size; + ~Vector() { + size += 1; + } +}; + +struct Base { + int b1; + double b2; + Base() { + b1 = 5; + b2 = 10.989; + } + virtual ~Base() {} +}; + +struct VirtualBase { + int vb1; + int vb2; + VirtualBase() { + vb1 = 10; + vb2 = 11; + } + virtual ~VirtualBase() {} +}; + +struct Derived : public Base, public virtual VirtualBase { + int d1; + Vector<int> v; + int d2; + Derived() { + d1 = 10; + } + ~Derived() {} +}; + +Derived d; + +// Destruction order: +// Derived: int, Vector, Base, VirtualBase + +// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev +// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev +// CHECK: ret void + +// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev +// CHECK: ret void + +// poison 2 ints +// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev +// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8) +// CHECK: ret void + +// poison int and double +// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev +// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16) +// CHECK: ret void + +// poison int, ignore vector, poison int +// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev +// CHECK: call void {{.*}}ZN6VectorIiED1Ev +// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4) +// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4) +// CHECK: call void {{.*}}ZN4BaseD2Ev +// CHECK: ret void + +// poison int +// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev +// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4) +// CHECK: ret void diff --git a/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp b/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp new file mode 100644 index 00000000000..28624a0e7ae --- /dev/null +++ b/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp @@ -0,0 +1,30 @@ +// Test -fsanitize-memory-use-after-dtor +// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s + +template <class T> +class Vector { +public: + int size; + ~Vector() {} +}; + +// Virtual function table for the derived class only contains +// its own destructors, with no aliasing to base class dtors. +struct Base { + Vector<int> v; + int x; + Base() { x = 5; } + virtual ~Base() {} +}; + +struct Derived : public Base { + int z; + Derived() { z = 10; } + ~Derived() {} +}; + +Derived d; + +// Definition of virtual function table +// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev |

