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}} 9struct 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}} 16struct 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 25struct LeadingChar { // no-warning 26 char c; 27 int i; 28}; 29 30struct TrailingChar { // no-warning 31 int i; 32 char c; 33}; 34 35struct Helpless { // no-warning 36 struct TrailingChar i1; 37 struct LeadingChar i2; 38 char c; 39}; 40 41#pragma pack(push) 42#pragma pack(1) 43struct 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 51struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}} 52 char c1; 53 int i; 54 char c2; 55}; 56 57struct 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) 65struct 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 76union SomeUnion { // no-warning 77 char c; 78 short s; 79 int i; 80}; 81 82struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}} 83 char c1; 84 union SomeUnion u; 85 char c2; 86}; 87 88struct BigCharArray { // no-warning 89 char c[129]; 90}; 91 92struct SmallCharArray { // no-warning 93 char c[5]; 94}; 95 96struct MediumIntArray { // no-warning 97 int i[5]; 98}; 99 100struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}} 101 struct BigCharArray b; 102 struct MediumIntArray m; 103 struct SmallCharArray s; 104}; 105 106struct 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 114struct 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 123struct 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 132typedef 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}} 139struct StructAttrAlign { 140 char c1; 141 int i; 142 char c2; 143} __attribute__((aligned(8))); 144 145struct 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 154struct 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 161struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}} 162 char c1; 163 struct OverlyAlignedChar o; 164 char c2; 165}; 166 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 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 185void anonStructFunc() { 186 struct { // expected-warning{{Excessive padding in 'struct (anonymous}} 187 char c1; 188 int t; 189 char c2; 190 } obj; 191} 192 193struct CorrectDefaultAttrAlign { // no-warning 194 long long i; 195 char c1; 196 char c2; 197} __attribute__((aligned)); 198 199struct TooSmallShortSandwich { // no-warning 200 char c1; 201 short s; 202 char c2; 203}; 204 205// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}} 206struct SmallArrayShortSandwich { 207 char c1; 208 short s; 209 char c2; 210} ShortArray[20]; 211 212// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}} 213struct SmallArrayInFunc { 214 char c1; 215 short s; 216 char c2; 217}; 218 219void arrayHolder() { 220 struct SmallArrayInFunc Arr[15]; 221} 222 223// xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}} 224struct SmallArrayInStruct { 225 char c1; 226 short s; 227 char c2; 228}; 229 230struct HoldsSmallArray { 231 struct SmallArrayInStruct Field[20]; 232} HoldsSmallArrayElt; 233 234void nestedPadding() { 235 struct HoldsSmallArray Arr[15]; 236} 237