reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
// RUN: %clang_analyze_cc1 -verify %s \
// RUN:   -analyzer-checker=optin.performance \
// RUN:   -analyzer-config optin.performance.Padding:AllowedPad=2

// RUN: not %clang_analyze_cc1 -verify %s \
// RUN:   -analyzer-checker=core \
// RUN:   -analyzer-checker=optin.performance.Padding \
// RUN:   -analyzer-config optin.performance.Padding:AllowedPad=-10 \
// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-PAD-NEGATIVE-VALUE

// CHECK-PAD-NEGATIVE-VALUE: (frontend): invalid input for checker option
// CHECK-PAD-NEGATIVE-VALUE-SAME: 'optin.performance.Padding:AllowedPad', that
// CHECK-PAD-NEGATIVE-VALUE-SAME: expects a non-negative value

#if __has_include(<stdalign.h>)
#include <stdalign.h>
#endif

#if __has_include(<stdalign.h>) || defined(__cplusplus)
// expected-warning@+1{{Excessive padding in 'struct FieldAttrAlign' (6 padding}}
struct FieldAttrAlign {
  char c1;
  alignas(4) int i;
  char c2;
};

// expected-warning@+1{{Excessive padding in 'struct FieldAttrOverAlign' (10 padding}}
struct FieldAttrOverAlign {
  char c1;
  alignas(8) int i;
  char c2;
};

#endif // __has_include(<stdalign.h>) || defined(__cplusplus)

// Re-ordering members of these structs won't reduce padding, so don't warn
struct LeadingChar { // no-warning
  char c;
  int i;
};

struct TrailingChar { // no-warning
  int i;
  char c;
};

struct Helpless { // no-warning
  struct TrailingChar i1;
  struct LeadingChar i2;
  char c;
};

#pragma pack(push)
#pragma pack(1)
struct SquishedIntSandwich { // no-warning
  char c1;
  int i;
  char c2;
};
#pragma pack(pop)

// Re-ordering members of these structs will reduce padding, so warn
struct IntSandwich { // expected-warning{{Excessive padding in 'struct IntSandwich'}}
  char c1;
  int i;
  char c2;
};

struct TurDuckHen { // expected-warning{{Excessive padding in 'struct TurDuckHen'}}
  char c1;
  struct IntSandwich i;
  char c2;
};

#pragma pack(push)
#pragma pack(2)
struct SmallIntSandwich { // expected-warning{{Excessive padding in 'struct SmallIntSandwich'}}
  char c1;
  int i1;
  char c2;
  int i2;
  char c3;
  int i3;
  char c4;
};
#pragma pack(pop)

union SomeUnion { // no-warning
  char c;
  short s;
  int i;
};

struct HoldsAUnion { // expected-warning{{Excessive padding in 'struct HoldsAUnion'}}
  char c1;
  union SomeUnion u;
  char c2;
};

struct BigCharArray { // no-warning
  char c[129];
};

struct SmallCharArray { // no-warning
  char c[5];
};

struct MediumIntArray { // no-warning
  int i[5];
};

struct LargeSizeToSmallSize { // expected-warning{{Excessive padding in 'struct LargeSizeToSmallSize'}}
  struct BigCharArray b;
  struct MediumIntArray m;
  struct SmallCharArray s;
};

struct LargeAlignToSmallAlign { // no-warning
  struct MediumIntArray m;
  struct BigCharArray b;
  struct SmallCharArray s;
};

// Currently ignoring VLA padding problems.  Still need to make sure we don't
// choke on VLAs though
struct HoldsVLA { // no-warning
  char c1;
  int x;
  char c2;
  int vla[];
};

// Currently ignoring bitfield padding problems.  Still need to make sure we
// don't choke on bitfields though
struct HoldsBitfield { // no-warning
  char c1;
  int x;
  char c2;
  unsigned char b1 : 3;
  unsigned char b2 : 3;
  unsigned char b3 : 2;
};

typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich'}}
  char c1;
  int i;
  char c2;
} TypedefSandwich;

// expected-warning@+1{{Excessive padding in 'struct StructAttrAlign' (10 padding}}
struct StructAttrAlign {
  char c1;
  int i;
  char c2;
} __attribute__((aligned(8)));

struct CorrectOverlyAlignedChar { // no-warning
  char c __attribute__((aligned(4096)));
  char c1;
  int x1;
  char c2;
  int x2;
  char c3;
};

struct OverlyAlignedChar { // expected-warning{{Excessive padding in 'struct OverlyAlignedChar'}}
  char c1;
  int x;
  char c2;
  char c __attribute__((aligned(4096)));
};

struct HoldsOverlyAlignedChar { // expected-warning{{Excessive padding in 'struct HoldsOverlyAlignedChar'}}
  char c1;
  struct OverlyAlignedChar o;
  char c2;
};

void internalStructFunc() {
  struct X { // expected-warning{{Excessive padding in 'struct X'}}
    char c1;
    int t;
    char c2;
  };
  struct X obj;
}

void typedefStructFunc() {
  typedef struct { // expected-warning{{Excessive padding in 'S'}}
    char c1;
    int t;
    char c2;
  } S;
  S obj;
}

void anonStructFunc() {
  struct { // expected-warning{{Excessive padding in 'struct (anonymous}}
    char c1;
    int t;
    char c2;
  } obj;
}

struct CorrectDefaultAttrAlign { // no-warning
  long long i;
  char c1;
  char c2;
} __attribute__((aligned));

struct TooSmallShortSandwich { // no-warning
  char c1;
  short s;
  char c2;
};

// expected-warning@+1{{Excessive padding in 'struct SmallArrayShortSandwich'}}
struct SmallArrayShortSandwich {
  char c1;
  short s;
  char c2;
} ShortArray[20];

// expected-warning@+1{{Excessive padding in 'struct SmallArrayInFunc'}}
struct SmallArrayInFunc {
  char c1;
  short s;
  char c2;
};

void arrayHolder() {
  struct SmallArrayInFunc Arr[15];
}

// xxxexpected-warning@+1{{Excessive padding in 'struct SmallArrayInStruct'}}
struct SmallArrayInStruct {
  char c1;
  short s;
  char c2;
};

struct HoldsSmallArray {
  struct SmallArrayInStruct Field[20];
} HoldsSmallArrayElt;

void nestedPadding() {
  struct HoldsSmallArray Arr[15];
}