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