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