1 // RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
2 
3 // expected-warning@+1{{Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal)}}
4 struct IntSandwich {
5   char c1;
6   int i;
7   char c2;
8 };
9 
10 // expected-warning@+1{{Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal)}}
11 struct TurDuckHen {
12   char c1;
13   struct IntSandwich i;
14   char c2;
15 };
16 
17 #pragma pack(push)
18 #pragma pack(2)
19 // expected-warning@+1{{Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal)}}
20 struct SmallIntSandwich {
21   char c1;
22   int i1;
23   char c2;
24   int i2;
25   char c3;
26   int i3;
27   char c4;
28 };
29 #pragma pack(pop)
30 
31 union SomeUnion { // no-warning
32   char c;
33   short s;
34   int i;
35 };
36 
37 // expected-warning@+1{{Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal)}}
38 struct HoldsAUnion {
39   char c1;
40   union SomeUnion u;
41   char c2;
42 };
43 
44 struct SmallCharArray { // no-warning
45   char c[5];
46 };
47 
48 struct MediumIntArray { // no-warning
49   int i[5];
50 };
51 
52 // expected-warning@+1{{Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal)}}
53 struct StructSandwich {
54   struct SmallCharArray s;
55   struct MediumIntArray m;
56   struct SmallCharArray s2;
57 };
58 
59 // expected-warning@+1{{Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal)}}
60 typedef struct {
61   char c1;
62   int i;
63   char c2;
64 } TypedefSandwich;
65 
66 // expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal)}}
67 struct StructAttrAlign {
68   char c1;
69   int i;
70   char c2;
71 } __attribute__((aligned(8)));
72 
73 // expected-warning@+1{{Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal)}}
74 struct OverlyAlignedChar {
75   char c1;
76   int x;
77   char c2;
78   char c __attribute__((aligned(4096)));
79 };
80 
81 // expected-warning@+1{{Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal)}}
82 struct HoldsOverlyAlignedChar {
83   char c1;
84   struct OverlyAlignedChar o;
85   char c2;
86 };
87 
internalStructFunc()88 void internalStructFunc() {
89   // expected-warning@+1{{Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal)}}
90   struct X {
91     char c1;
92     int t;
93     char c2;
94   };
95   struct X obj;
96 }
97 
typedefStructFunc()98 void typedefStructFunc() {
99   // expected-warning@+1{{Excessive padding in 'S' (6 padding bytes, where 2 is optimal)}}
100   typedef struct {
101     char c1;
102     int t;
103     char c2;
104   } S;
105   S obj;
106 }
107 
108 // expected-warning@+1{{Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal)}}
109 struct DefaultAttrAlign {
110   char c1;
111   long long i;
112   char c2;
113 } __attribute__((aligned));
114 
115 // expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal)}}
116 struct SmallArrayShortSandwich {
117   char c1;
118   short s;
119   char c2;
120 } ShortArray[20];
121 
122 // expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal)}}
123 struct SmallArrayInFunc {
124   char c1;
125   short s;
126   char c2;
127 };
128 
arrayHolder()129 void arrayHolder() {
130   struct SmallArrayInFunc Arr[15];
131 }
132 
133 // expected-warning@+1{{Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal)}}
134 class VirtualIntSandwich {
foo()135   virtual void foo() {}
136   char c1;
137   int i;
138   char c2;
139 };
140 
141 // constructed so as not to have tail padding
142 // expected-warning@+1{{Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal)}}
143 class InnerPaddedB {
144   char c1;
145   int i1;
146   char c2;
147   int i2;
148 };
149 
150 class Empty {}; // no-warning
151 
152 // expected-warning@+1{{Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal)}}
153 class LotsOfSpace {
154   Empty e1;
155   int i;
156   Empty e2;
157 };
158 
159 // expected-warning@+1{{Excessive padding in 'TypedefSandwich2' (6 padding bytes, where 2 is optimal)}}
160 typedef struct {
161   char c1;
162   // expected-warning@+1{{Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal)}}
163   typedef struct {
164     char c1;
165     int i;
166     char c2;
167   } NestedTypedef;
168   NestedTypedef t;
169   char c2;
170 } TypedefSandwich2;
171 
172 template <typename T>
173 struct Foo {
174   // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested' (6 padding bytes, where 2 is optimal)}}
175   struct Nested {
176     char c1;
177     T t;
178     char c2;
179   };
180 };
181 
182 struct Holder { // no-warning
183   Foo<int>::Nested t1;
184   Foo<char>::Nested t2;
185 };
186