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
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
5 // 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
6 // RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING
7 // REQUIRES: shell
8 //
9 
10 // The reasons to ignore a particular class are not set in stone and will change.
11 //
12 // CHECK: -fsanitize-address-field-padding applied to Positive1
13 // CHECK: -fsanitize-address-field-padding ignored for Negative1 because it is trivially copyable
14 // CHECK: -fsanitize-address-field-padding ignored for Negative2 because it is trivially copyable
15 // CHECK: -fsanitize-address-field-padding ignored for Negative3 because it is a union
16 // CHECK: -fsanitize-address-field-padding ignored for Negative4 because it is trivially copyable
17 // CHECK: -fsanitize-address-field-padding ignored for Negative5 because it is packed
18 // CHECK: -fsanitize-address-field-padding ignored for SomeNamespace::BlacklistedByName because it is blacklisted
19 // CHECK: -fsanitize-address-field-padding ignored for ExternCStruct because it is not C++
20 //
21 // FILE_BLACKLIST: -fsanitize-address-field-padding ignored for Positive1 because it is in a blacklisted file
22 // FILE_BLACKLIST-NOT: __asan_poison_intra_object_redzone
23 // NO_PADDING-NOT: __asan_poison_intra_object_redzone
24 
25 
26 class Positive1 {
27  public:
28   Positive1() {}
29   ~Positive1() {}
30   int make_it_non_standard_layout;
31  private:
32   char private1;
33   int private2;
34   short private_array[6];
35   long long private3;
36 };
37 
38 Positive1 positive1;
39 // Positive1 with extra paddings
40 // 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 
42 struct VirtualBase {
43   int foo;
44 };
45 
46 class ClassWithVirtualBase : public virtual VirtualBase {
47  public:
48   ClassWithVirtualBase() {}
49   ~ClassWithVirtualBase() {}
50   int make_it_non_standard_layout;
51  private:
52   char x[7];
53   char y[9];
54 };
55 
56 ClassWithVirtualBase class_with_virtual_base;
57 
58 
59 class Negative1 {
60  public:
61   Negative1() {}
62   int public1, public2;
63 };
64 Negative1 negative1;
65 // CHECK: type { i32, i32 }
66 
67 class Negative2 {
68  public:
69   Negative2() {}
70  private:
71   int private1, private2;
72 };
73 Negative2 negative2;
74 // CHECK: type { i32, i32 }
75 
76 union Negative3 {
77   char m1[8];
78   long long m2;
79 };
80 
81 Negative3 negative3;
82 // CHECK: type { i64 }
83 
84 class Negative4 {
85  public:
86   Negative4() {}
87   // No DTOR
88   int make_it_non_standard_layout;
89  private:
90   char private1;
91   int private2;
92 };
93 
94 Negative4 negative4;
95 // CHECK: type { i32, i8, i32 }
96 
97 class __attribute__((packed)) Negative5 {
98  public:
99   Negative5() {}
100   ~Negative5() {}
101   int make_it_non_standard_layout;
102  private:
103   char private1;
104   int private2;
105 };
106 
107 Negative5 negative5;
108 // CHECK: type <{ i32, i8, i32 }>
109 
110 
111 namespace SomeNamespace {
112 class BlacklistedByName {
113  public:
114   BlacklistedByName() {}
115   ~BlacklistedByName() {}
116   int make_it_non_standard_layout;
117  private:
118   char private1;
119   int private2;
120 };
121 }  // SomeNamespace
122 
123 SomeNamespace::BlacklistedByName blacklisted_by_name;
124 
125 extern "C" {
126 class ExternCStruct {
127  public:
128   ExternCStruct() {}
129   ~ExternCStruct() {}
130   int make_it_non_standard_layout;
131  private:
132   char private1;
133   int private2;
134 };
135 }  // extern "C"
136 
137 ExternCStruct extern_C_struct;
138 
139 // CTOR
140 // CHECK-LABEL: define {{.*}}Positive1C1Ev
141 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12)
142 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}15)
143 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12)
144 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12)
145 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}8)
146 // CHECK-NOT: __asan_poison_intra_object_redzone
147 // CHECK: ret void
148 //
149 // DTOR
150 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12)
151 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}15)
152 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12)
153 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12)
154 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}8)
155 // CHECK-NOT: __asan_unpoison_intra_object_redzone
156 // CHECK: ret void
157 //
158 //
159 // CHECK-LABEL: define linkonce_odr void @_ZN20ClassWithVirtualBaseC1Ev
160 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 12)
161 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 9)
162 // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 15)
163 // CHECK-NOT: __asan_poison_intra_object_redzone
164 // CHECK: ret void
165 //
166