1 // RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s 2 3 #if __has_include(<stdalign.h>) 4 #include <stdalign.h> 5 #endif 6 7 #if __has_include(<stdalign.h>) || defined(__cplusplus) 8 // expected-warning@+1{{Excessive padding in 'struct FieldAttrAlign' (6 padding}} 9 struct FieldAttrAlign { 10 char c1; 11 alignas(4) int i; 12 char c2; 13 }; 14 15 // expected-warning@+1{{Excessive padding in 'struct FieldAttrOverAlign' (10 padding}} 16 struct FieldAttrOverAlign { 17 char c1; 18 alignas(8) int i; 19 char c2; 20 }; 21 22 #endif // __has_include(<stdalign.h>) || defined(__cplusplus) 23 24 // Re-ordering members of these structs won't reduce padding, so don't warn 25 struct LeadingChar { // no-warning 26 char c; 27 int i; 28 }; 29 30 struct TrailingChar { // no-warning 31 int i; 32 char c; 33 }; 34 35 struct Helpless { // no-warning 36 struct TrailingChar i1; 37 struct LeadingChar i2; 38 char c; 39 }; 40 41 #pragma pack(push) 42 #pragma pack(1) 43 struct SquishedIntSandwich { // no-warning 44 char c1; 45 int i; 46 char c2; 47 }; 48 #pragma pack(pop) 49 50 // Re-ordering members of these structs will reduce padding, so warn 51 struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}} 52 char c1; 53 int i; 54 char c2; 55 }; 56 57 struct TurDuckHen { // expected-warning{{Excessive padding in 'struct TurDuckHen'}} 58 char c1; 59 struct IntSandwich i; 60 char c2; 61 }; 62 63 #pragma pack(push) 64 #pragma pack(2) 65 struct SmallIntSandwich { // expected-warning{{Excessive padding in 'struct SmallIntSandwich'}} 66 char c1; 67 int i1; 68 char c2; 69 int i2; 70 char c3; 71 int i3; 72 char c4; 73 }; 74 #pragma pack(pop) 75 76 union SomeUnion { // no-warning 77 char c; 78 short s; 79 int i; 80 }; 81 82 struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}} 83 char c1; 84 union SomeUnion u; 85 char c2; 86 }; 87 88 struct BigCharArray { // no-warning 89 char c[129]; 90 }; 91 92 struct SmallCharArray { // no-warning 93 char c[5]; 94 }; 95 96 struct MediumIntArray { // no-warning 97 int i[5]; 98 }; 99 100 struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}} 101 struct BigCharArray b; 102 struct MediumIntArray m; 103 struct SmallCharArray s; 104 }; 105 106 struct LargeAlignToSmallAlign { // no-warning 107 struct MediumIntArray m; 108 struct BigCharArray b; 109 struct SmallCharArray s; 110 }; 111 112 // Currently ignoring VLA padding problems. Still need to make sure we don't 113 // choke on VLAs though 114 struct HoldsVLA { // no-warning 115 char c1; 116 int x; 117 char c2; 118 int vla[]; 119 }; 120 121 // Currently ignoring bitfield padding problems. Still need to make sure we 122 // don't choke on bitfields though 123 struct HoldsBitfield { // no-warning 124 char c1; 125 int x; 126 char c2; 127 unsigned char b1 : 3; 128 unsigned char b2 : 3; 129 unsigned char b3 : 2; 130 }; 131 132 typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich'}} 133 char c1; 134 int i; 135 char c2; 136 } TypedefSandwich; 137 138 // expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding}} 139 struct StructAttrAlign { 140 char c1; 141 int i; 142 char c2; 143 } __attribute__((aligned(8))); 144 145 struct CorrectOverlyAlignedChar { // no-warning 146 char c __attribute__((aligned(4096))); 147 char c1; 148 int x1; 149 char c2; 150 int x2; 151 char c3; 152 }; 153 154 struct OverlyAlignedChar { // expected-warning{{Excessive padding in 'struct OverlyAlignedChar'}} 155 char c1; 156 int x; 157 char c2; 158 char c __attribute__((aligned(4096))); 159 }; 160 161 struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}} 162 char c1; 163 struct OverlyAlignedChar o; 164 char c2; 165 }; 166 internalStructFunc()167void internalStructFunc() { 168 struct X { // expected-warning{{Excessive padding in 'struct X'}} 169 char c1; 170 int t; 171 char c2; 172 }; 173 struct X obj; 174 } 175 typedefStructFunc()176void typedefStructFunc() { 177 typedef struct { // expected-warning{{Excessive padding in 'S'}} 178 char c1; 179 int t; 180 char c2; 181 } S; 182 S obj; 183 } 184 anonStructFunc()185void anonStructFunc() { 186 struct { // expected-warning{{Excessive padding in 'struct (anonymous}} 187 char c1; 188 int t; 189 char c2; 190 } obj; 191 } 192 193 struct CorrectDefaultAttrAlign { // no-warning 194 long long i; 195 char c1; 196 char c2; 197 } __attribute__((aligned)); 198 199 struct TooSmallShortSandwich { // no-warning 200 char c1; 201 short s; 202 char c2; 203 }; 204 205 // expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}} 206 struct SmallArrayShortSandwich { 207 char c1; 208 short s; 209 char c2; 210 } ShortArray[20]; 211 212 // expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}} 213 struct SmallArrayInFunc { 214 char c1; 215 short s; 216 char c2; 217 }; 218 arrayHolder()219void arrayHolder() { 220 struct SmallArrayInFunc Arr[15]; 221 } 222 223 // xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}} 224 struct SmallArrayInStruct { 225 char c1; 226 short s; 227 char c2; 228 }; 229 230 struct HoldsSmallArray { 231 struct SmallArrayInStruct Field[20]; 232 } HoldsSmallArrayElt; 233 nestedPadding()234void nestedPadding() { 235 struct HoldsSmallArray Arr[15]; 236 } 237