Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 1 | // Test -fsanitize-address-field-padding |
| 2 | // RUN: echo 'type:SomeNamespace::BlacklistedByName=field-padding' > %t.type.blacklist |
| 3 | // RUN: echo 'src:*sanitize-address-field-padding.cpp=field-padding' > %t.file.blacklist |
NAKAMURA Takumi | e316722 | 2014-10-17 12:48:01 +0000 | [diff] [blame] | 4 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.type.blacklist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s |
Kostya Serebryany | 5f1b4e8 | 2014-10-31 19:01:02 +0000 | [diff] [blame] | 5 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.type.blacklist -Rsanitize-address -emit-llvm -o - %s -O1 -mconstructor-aliases 2>&1 | FileCheck %s --check-prefix=WITH_CTOR_ALIASES |
NAKAMURA Takumi | e316722 | 2014-10-17 12:48:01 +0000 | [diff] [blame] | 6 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.file.blacklist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=FILE_BLACKLIST |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 7 | // RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING |
Steven Wu | 3db51cb | 2015-07-17 20:49:01 +0000 | [diff] [blame] | 8 | // Try to emulate -save-temps option and make sure -disable-llvm-passes will not run sanitize instrumentation. |
| 9 | // RUN: %clang_cc1 -fsanitize=address -emit-llvm -disable-llvm-passes -o - %s | %clang_cc1 -fsanitize=address -emit-llvm -o - -x ir | FileCheck %s --check-prefix=NO_PADDING |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 10 | // |
| 11 | |
| 12 | // The reasons to ignore a particular class are not set in stone and will change. |
| 13 | // |
| 14 | // CHECK: -fsanitize-address-field-padding applied to Positive1 |
| 15 | // CHECK: -fsanitize-address-field-padding ignored for Negative1 because it is trivially copyable |
| 16 | // CHECK: -fsanitize-address-field-padding ignored for Negative2 because it is trivially copyable |
| 17 | // CHECK: -fsanitize-address-field-padding ignored for Negative3 because it is a union |
| 18 | // CHECK: -fsanitize-address-field-padding ignored for Negative4 because it is trivially copyable |
| 19 | // CHECK: -fsanitize-address-field-padding ignored for Negative5 because it is packed |
| 20 | // CHECK: -fsanitize-address-field-padding ignored for SomeNamespace::BlacklistedByName because it is blacklisted |
Kostya Serebryany | 23387754 | 2014-10-17 00:47:30 +0000 | [diff] [blame] | 21 | // CHECK: -fsanitize-address-field-padding ignored for ExternCStruct because it is not C++ |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 22 | // |
| 23 | // FILE_BLACKLIST: -fsanitize-address-field-padding ignored for Positive1 because it is in a blacklisted file |
| 24 | // FILE_BLACKLIST-NOT: __asan_poison_intra_object_redzone |
| 25 | // NO_PADDING-NOT: __asan_poison_intra_object_redzone |
| 26 | |
| 27 | |
| 28 | class Positive1 { |
| 29 | public: |
| 30 | Positive1() {} |
| 31 | ~Positive1() {} |
| 32 | int make_it_non_standard_layout; |
| 33 | private: |
| 34 | char private1; |
| 35 | int private2; |
| 36 | short private_array[6]; |
| 37 | long long private3; |
| 38 | }; |
| 39 | |
| 40 | Positive1 positive1; |
| 41 | // Positive1 with extra paddings |
| 42 | // CHECK: type { i32, [12 x i8], i8, [15 x i8], i32, [12 x i8], [6 x i16], [12 x i8], i64, [8 x i8] } |
| 43 | |
Kostya Serebryany | 6444921 | 2014-10-17 21:02:13 +0000 | [diff] [blame] | 44 | struct VirtualBase { |
| 45 | int foo; |
| 46 | }; |
| 47 | |
| 48 | class ClassWithVirtualBase : public virtual VirtualBase { |
| 49 | public: |
| 50 | ClassWithVirtualBase() {} |
| 51 | ~ClassWithVirtualBase() {} |
| 52 | int make_it_non_standard_layout; |
| 53 | private: |
| 54 | char x[7]; |
| 55 | char y[9]; |
| 56 | }; |
| 57 | |
| 58 | ClassWithVirtualBase class_with_virtual_base; |
| 59 | |
Kostya Serebryany | 68c29da | 2014-10-27 19:34:10 +0000 | [diff] [blame] | 60 | class WithFlexibleArray1 { |
| 61 | public: |
| 62 | WithFlexibleArray1() {} |
| 63 | ~WithFlexibleArray1() {} |
| 64 | int make_it_non_standard_layout; |
| 65 | private: |
| 66 | char private1[33]; |
| 67 | int flexible[]; // Don't insert padding after this field. |
| 68 | }; |
| 69 | |
| 70 | WithFlexibleArray1 with_flexible_array1; |
| 71 | // CHECK: %class.WithFlexibleArray1 = type { i32, [12 x i8], [33 x i8], [15 x i8], [0 x i32] } |
| 72 | |
| 73 | class WithFlexibleArray2 { |
| 74 | public: |
| 75 | char x[21]; |
| 76 | WithFlexibleArray1 flex1; // Don't insert padding after this field. |
| 77 | }; |
| 78 | |
| 79 | WithFlexibleArray2 with_flexible_array2; |
| 80 | // CHECK: %class.WithFlexibleArray2 = type { [21 x i8], [11 x i8], %class.WithFlexibleArray1 } |
| 81 | |
| 82 | class WithFlexibleArray3 { |
| 83 | public: |
| 84 | char x[13]; |
| 85 | WithFlexibleArray2 flex2; // Don't insert padding after this field. |
| 86 | }; |
| 87 | |
| 88 | WithFlexibleArray3 with_flexible_array3; |
| 89 | |
Kostya Serebryany | 6444921 | 2014-10-17 21:02:13 +0000 | [diff] [blame] | 90 | |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 91 | class Negative1 { |
| 92 | public: |
| 93 | Negative1() {} |
| 94 | int public1, public2; |
| 95 | }; |
| 96 | Negative1 negative1; |
| 97 | // CHECK: type { i32, i32 } |
| 98 | |
| 99 | class Negative2 { |
| 100 | public: |
| 101 | Negative2() {} |
| 102 | private: |
| 103 | int private1, private2; |
| 104 | }; |
| 105 | Negative2 negative2; |
| 106 | // CHECK: type { i32, i32 } |
| 107 | |
| 108 | union Negative3 { |
| 109 | char m1[8]; |
| 110 | long long m2; |
| 111 | }; |
| 112 | |
| 113 | Negative3 negative3; |
| 114 | // CHECK: type { i64 } |
| 115 | |
| 116 | class Negative4 { |
| 117 | public: |
| 118 | Negative4() {} |
| 119 | // No DTOR |
| 120 | int make_it_non_standard_layout; |
| 121 | private: |
| 122 | char private1; |
| 123 | int private2; |
| 124 | }; |
| 125 | |
| 126 | Negative4 negative4; |
| 127 | // CHECK: type { i32, i8, i32 } |
| 128 | |
| 129 | class __attribute__((packed)) Negative5 { |
| 130 | public: |
| 131 | Negative5() {} |
| 132 | ~Negative5() {} |
| 133 | int make_it_non_standard_layout; |
| 134 | private: |
| 135 | char private1; |
| 136 | int private2; |
| 137 | }; |
| 138 | |
| 139 | Negative5 negative5; |
| 140 | // CHECK: type <{ i32, i8, i32 }> |
| 141 | |
| 142 | |
| 143 | namespace SomeNamespace { |
| 144 | class BlacklistedByName { |
| 145 | public: |
| 146 | BlacklistedByName() {} |
| 147 | ~BlacklistedByName() {} |
| 148 | int make_it_non_standard_layout; |
| 149 | private: |
| 150 | char private1; |
| 151 | int private2; |
| 152 | }; |
| 153 | } // SomeNamespace |
| 154 | |
| 155 | SomeNamespace::BlacklistedByName blacklisted_by_name; |
| 156 | |
| 157 | extern "C" { |
| 158 | class ExternCStruct { |
| 159 | public: |
| 160 | ExternCStruct() {} |
| 161 | ~ExternCStruct() {} |
| 162 | int make_it_non_standard_layout; |
| 163 | private: |
| 164 | char private1; |
| 165 | int private2; |
| 166 | }; |
| 167 | } // extern "C" |
| 168 | |
| 169 | ExternCStruct extern_C_struct; |
| 170 | |
| 171 | // CTOR |
Renato Golin | 031e817 | 2014-10-17 10:09:25 +0000 | [diff] [blame] | 172 | // CHECK-LABEL: define {{.*}}Positive1C1Ev |
Kostya Serebryany | 330e9f6 | 2014-10-16 21:22:40 +0000 | [diff] [blame] | 173 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) |
| 174 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}15) |
| 175 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) |
| 176 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) |
| 177 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}8) |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 178 | // CHECK-NOT: __asan_poison_intra_object_redzone |
| 179 | // CHECK: ret void |
Kostya Serebryany | 23387754 | 2014-10-17 00:47:30 +0000 | [diff] [blame] | 180 | // |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 181 | // DTOR |
Kostya Serebryany | 330e9f6 | 2014-10-16 21:22:40 +0000 | [diff] [blame] | 182 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) |
| 183 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}15) |
| 184 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) |
| 185 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) |
| 186 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}8) |
Kostya Serebryany | 293dc9b | 2014-10-16 20:54:52 +0000 | [diff] [blame] | 187 | // CHECK-NOT: __asan_unpoison_intra_object_redzone |
| 188 | // CHECK: ret void |
Kostya Serebryany | 6444921 | 2014-10-17 21:02:13 +0000 | [diff] [blame] | 189 | // |
| 190 | // |
| 191 | // CHECK-LABEL: define linkonce_odr void @_ZN20ClassWithVirtualBaseC1Ev |
| 192 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 12) |
| 193 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 9) |
| 194 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 15) |
| 195 | // CHECK-NOT: __asan_poison_intra_object_redzone |
| 196 | // CHECK: ret void |
| 197 | // |
Kostya Serebryany | 5f1b4e8 | 2014-10-31 19:01:02 +0000 | [diff] [blame] | 198 | |
| 199 | struct WithVirtualDtor { |
| 200 | virtual ~WithVirtualDtor(); |
| 201 | int x, y; |
| 202 | }; |
| 203 | struct InheritsFrom_WithVirtualDtor: WithVirtualDtor { |
| 204 | int a, b; |
| 205 | InheritsFrom_WithVirtualDtor() {} |
| 206 | ~InheritsFrom_WithVirtualDtor() {} |
| 207 | }; |
| 208 | |
| 209 | void Create_InheritsFrom_WithVirtualDtor() { |
| 210 | InheritsFrom_WithVirtualDtor x; |
| 211 | } |
| 212 | |
| 213 | |
| 214 | // Make sure the dtor of InheritsFrom_WithVirtualDtor remains in the code, |
| 215 | // i.e. we ignore -mconstructor-aliases when field paddings are added |
| 216 | // because the paddings in InheritsFrom_WithVirtualDtor needs to be unpoisoned |
| 217 | // in the dtor. |
| 218 | // WITH_CTOR_ALIASES-LABEL: define void @_Z35Create_InheritsFrom_WithVirtualDtor |
| 219 | // WITH_CTOR_ALIASES-NOT: call void @_ZN15WithVirtualDtorD2Ev |
| 220 | // WITH_CTOR_ALIASES: call void @_ZN28InheritsFrom_WithVirtualDtorD2Ev |
| 221 | // WITH_CTOR_ALIASES: ret void |
Kostya Serebryany | 4133eab | 2014-11-11 23:38:13 +0000 | [diff] [blame] | 222 | |
| 223 | // Make sure we don't emit memcpy for operator= if paddings are inserted. |
| 224 | struct ClassWithTrivialCopy { |
| 225 | ClassWithTrivialCopy(); |
| 226 | ~ClassWithTrivialCopy(); |
| 227 | void *a; |
| 228 | private: |
| 229 | void *c; |
| 230 | }; |
| 231 | |
| 232 | void MakeTrivialCopy(ClassWithTrivialCopy *s1, ClassWithTrivialCopy *s2) { |
| 233 | *s1 = *s2; |
Kostya Serebryany | 597dcc7 | 2014-12-06 01:23:08 +0000 | [diff] [blame] | 234 | ClassWithTrivialCopy s3(*s2); |
Kostya Serebryany | 4133eab | 2014-11-11 23:38:13 +0000 | [diff] [blame] | 235 | } |
| 236 | |
| 237 | // CHECK-LABEL: define void @_Z15MakeTrivialCopyP20ClassWithTrivialCopyS0_ |
| 238 | // CHECK-NOT: memcpy |
| 239 | // CHECK: ret void |