aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/padding_c.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/padding_c.c')
-rw-r--r--test/Analysis/padding_c.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/test/Analysis/padding_c.c b/test/Analysis/padding_c.c
new file mode 100644
index 000000000000..93cefcad8930
--- /dev/null
+++ b/test/Analysis/padding_c.c
@@ -0,0 +1,236 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+
+#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];
+}