Home | History | Annotate | Download | only in Analysis
      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 
    167 void 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 
    176 void 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 
    185 void 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 
    219 void 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 
    234 void nestedPadding() {
    235   struct HoldsSmallArray Arr[15];
    236 }
    237