1 // Test -fsanitize-address-field-padding
2 // RUN: echo 'type:SomeNamespace::IgnorelistedByName=field-padding' > %t.type.ignorelist
3 // RUN: echo 'src:*sanitize-address-field-padding.cpp=field-padding' > %t.file.ignorelist
4 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-ignorelist=%t.type.ignorelist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s
5 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-ignorelist=%t.type.ignorelist -Rsanitize-address -emit-llvm -o - %s -mconstructor-aliases 2>&1 | FileCheck %s --check-prefix=WITH_CTOR_ALIASES
6 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-ignorelist=%t.file.ignorelist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=FILE_IGNORELIST
7 // RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING
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
12 // The reasons to ignore a particular class are not set in stone and will change.
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::IgnorelistedByName because it is ignorelisted
21 // CHECK: -fsanitize-address-field-padding ignored for ExternCStruct because it is not C++
23 // FILE_IGNORELIST: -fsanitize-address-field-padding ignored for Positive1 because it is in a ignorelisted file
24 // FILE_IGNORELIST-NOT: __asan_poison_intra_object_redzone
25 // NO_PADDING-NOT: __asan_poison_intra_object_redzone
32 int make_it_non_standard_layout
;
36 short private_array
[6];
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] }
48 class ClassWithVirtualBase
: public virtual VirtualBase
{
50 ClassWithVirtualBase() {}
51 ~ClassWithVirtualBase() {}
52 int make_it_non_standard_layout
;
58 ClassWithVirtualBase class_with_virtual_base
;
60 class WithFlexibleArray1
{
62 WithFlexibleArray1() {}
63 ~WithFlexibleArray1() {}
64 int make_it_non_standard_layout
;
67 int flexible
[]; // Don't insert padding after this field.
70 WithFlexibleArray1 with_flexible_array1
;
71 // CHECK: %class.WithFlexibleArray1 = type { i32, [12 x i8], [33 x i8], [15 x i8], [0 x i32] }
73 class WithFlexibleArray2
{
76 WithFlexibleArray1 flex1
; // Don't insert padding after this field.
79 WithFlexibleArray2 with_flexible_array2
;
80 // CHECK: %class.WithFlexibleArray2 = type { [21 x i8], [11 x i8], %class.WithFlexibleArray1 }
82 class WithFlexibleArray3
{
85 WithFlexibleArray2 flex2
; // Don't insert padding after this field.
88 WithFlexibleArray3 with_flexible_array3
;
97 // CHECK: type { i32, i32 }
103 int private1
, private2
;
106 // CHECK: type { i32, i32 }
114 // CHECK: type { i64 }
120 int make_it_non_standard_layout
;
127 // CHECK: type { i32, i8, i32 }
129 class __attribute__((packed
)) Negative5
{
133 int make_it_non_standard_layout
;
140 // CHECK: type <{ i32, i8, i32 }>
143 namespace SomeNamespace
{
144 class IgnorelistedByName
{
146 IgnorelistedByName() {}
147 ~IgnorelistedByName() {}
148 int make_it_non_standard_layout
;
155 SomeNamespace::IgnorelistedByName ignorelisted_by_name
;
158 class ExternCStruct
{
162 int make_it_non_standard_layout
;
169 ExternCStruct extern_C_struct
;
172 // CHECK-LABEL: define {{.*}}Positive1C1Ev
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)
178 // CHECK-NOT: __asan_poison_intra_object_redzone
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)
187 // CHECK-NOT: __asan_unpoison_intra_object_redzone
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
199 struct WithVirtualDtor
{
200 virtual ~WithVirtualDtor();
203 struct InheritsFrom_WithVirtualDtor
: WithVirtualDtor
{
205 InheritsFrom_WithVirtualDtor() {}
206 ~InheritsFrom_WithVirtualDtor() {}
209 void Create_InheritsFrom_WithVirtualDtor() {
210 InheritsFrom_WithVirtualDtor x
;
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
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
223 // Make sure we don't emit memcpy for operator= if paddings are inserted.
224 struct ClassWithTrivialCopy
{
225 ClassWithTrivialCopy();
226 ~ClassWithTrivialCopy();
232 void MakeTrivialCopy(ClassWithTrivialCopy
*s1
, ClassWithTrivialCopy
*s2
) {
234 ClassWithTrivialCopy
s3(*s2
);
237 // CHECK-LABEL: define{{.*}} void @_Z15MakeTrivialCopyP20ClassWithTrivialCopyS0_