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