1// RUN: %check_clang_tidy %s altera-struct-pack-align %t -- -header-filter=.*
2
3// Struct needs both alignment and packing
4struct error {
5 char a;
6 double b;
7 char c;
8};
9// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error' is inefficient due to padding; only needs 10 bytes but is using 24 bytes [altera-struct-pack-align]
10// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'error'
11// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'error' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
12// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error' to 16 bytes
13// CHECK-FIXES: __attribute__((packed))
14// CHECK-FIXES: __attribute__((aligned(16)));
15
16// Struct is explicitly packed, but needs alignment
17struct error_packed {
18 char a;
19 double b;
20 char c;
21} __attribute__((packed));
22// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error_packed' is inefficient due to poor alignment; currently aligned to 1 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
23// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error_packed' to 16 bytes
24// CHECK-FIXES: __attribute__((aligned(16)))
25
26// Struct is properly packed, but needs alignment
27struct align_only {
28 char a;
29 char b;
30 char c;
31 char d;
32 int e;
33 double f;
34};
35// CHECK-MESSAGES: :[[@LINE-8]]:8: warning: accessing fields in struct 'align_only' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
36// CHECK-MESSAGES: :[[@LINE-9]]:8: note: use "__attribute__((aligned(16)))" to align struct 'align_only' to 16 bytes
37// CHECK-FIXES: __attribute__((aligned(16)));
38
39// Struct is perfectly packed but wrongly aligned
40struct bad_align {
41 char a;
42 double b;
43 char c;
44} __attribute__((packed)) __attribute__((aligned(8)));
45// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
46// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align' to 16 bytes
47// CHECK-FIXES: __attribute__((aligned(16)));
48
49struct bad_align2 {
50 char a;
51 double b;
52 char c;
53} __attribute__((packed)) __attribute__((aligned(32)));
54// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align2' is inefficient due to poor alignment; currently aligned to 32 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
55// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align2' to 16 bytes
56// CHECK-FIXES: __attribute__((aligned(16)));
57
58struct bad_align3 {
59 char a;
60 double b;
61 char c;
62} __attribute__((packed)) __attribute__((aligned(4)));
63// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align3' is inefficient due to poor alignment; currently aligned to 4 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
64// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align3' to 16 bytes
65// CHECK-FIXES: __attribute__((aligned(16)));
66
67// Struct is both perfectly packed and aligned
68struct success {
69 char a;
70 double b;
71 char c;
72} __attribute__((packed)) __attribute__((aligned(16)));
73//Should take 10 bytes and be aligned to 16 bytes
74
75// Struct is properly packed, and explicitly aligned
76struct success2 {
77 int a;
78 int b;
79 int c;
80} __attribute__((aligned(16)));
81
82// If struct is properly aligned, packing not needed
83struct success3 {
84 char a;
85 double b;
86 char c;
87} __attribute__((aligned(16)));
88
89// If struct is templated, warnings should not be triggered
90template <typename A, typename B>
91struct success4 {
92 A a;
93 B b;
94 int c;
95};
96
97// Warnings should not trigger on struct instantiations
98void no_trigger_on_instantiation() {
99 struct bad_align3 instantiated { .a: 'a', .b: 0.001, .c: 'b' };
100}
101
102// Make sure that we don't recommend aligning an empty struct to zero bytes (PR#51620)
103struct StructWithNoFields {};
104
105struct ContainsStructWithNoFields {
106 StructWithNoFields s;
107};
108
109// Make sure that an empty struct is treated like "char" for padding and alignment purposes
110struct ContainsStructWithNoFields2 {
111 StructWithNoFields s;
112 double d;
113 StructWithNoFields t;
114};
115// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'ContainsStructWithNoFields2' is inefficient due to padding; only needs 10 bytes but is using 24 bytes [altera-struct-pack-align]
116// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'ContainsStructWithNoFields2'
117// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'ContainsStructWithNoFields2' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
118// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'ContainsStructWithNoFields2' to 16 bytes
119// CHECK-FIXES: __attribute__((packed))
120// CHECK-FIXES: __attribute__((aligned(16)));
121

source code of clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp