1 | // RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-tagged-union-member-count %t \ |
2 | // RUN: -config='{CheckOptions: { \ |
3 | // RUN: bugprone-tagged-union-member-count.StrictMode: false, \ |
4 | // RUN: bugprone-tagged-union-member-count.EnableCountingEnumHeuristic: true, \ |
5 | // RUN: bugprone-tagged-union-member-count.CountingEnumSuffixes: "count", \ |
6 | // RUN: bugprone-tagged-union-member-count.CountingEnumPrefixes: "last", \ |
7 | // RUN: }}' -- |
8 | |
9 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (3) than tags (2) |
10 | struct IncorrectBecauseHeuristicIsEnabledPrefixCase { |
11 | enum { |
12 | tags1, |
13 | tags2, |
14 | lasttag, |
15 | } Tags; |
16 | union { |
17 | char A; |
18 | short B; |
19 | int C; |
20 | } Data; |
21 | }; |
22 | |
23 | struct CorrectBecauseHeuristicIsEnabledPrefixCase { // No warnings expected |
24 | enum { |
25 | tags1, |
26 | tags2, |
27 | tags3, |
28 | lasttag, |
29 | } Tags; |
30 | union { |
31 | int A; |
32 | int B; |
33 | int C; |
34 | } Data; |
35 | }; |
36 | |
37 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (3) than tags (2) |
38 | struct IncorrectBecauseHeuristicIsEnabledSuffixCase { |
39 | enum { |
40 | tags1, |
41 | tags2, |
42 | tags_count, |
43 | } Tags; |
44 | union { |
45 | char A; |
46 | short B; |
47 | int C; |
48 | } Data; |
49 | }; |
50 | |
51 | struct CorrectBecauseHeuristicIsEnabledSuffixCase { // No warnings expected |
52 | enum { |
53 | tags1, |
54 | tags2, |
55 | tags3, |
56 | tags_count, |
57 | } Tags; |
58 | union { |
59 | int A; |
60 | int B; |
61 | int C; |
62 | } Data; |
63 | }; |
64 | |
65 | union Union4 { |
66 | short *Shorts; |
67 | double *Doubles; |
68 | int *Ints; |
69 | float *Floats; |
70 | }; |
71 | |
72 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3) |
73 | struct CountingEnumCaseInsensitivityTest1 { |
74 | enum { |
75 | node_type_loop, |
76 | node_type_branch, |
77 | node_type_function, |
78 | node_type_count, |
79 | } Kind; |
80 | union Union4 Data; |
81 | }; |
82 | |
83 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3) |
84 | struct CountingEnumCaseInsensitivityTest2 { |
85 | enum { |
86 | NODE_TYPE_LOOP, |
87 | NODE_TYPE_BRANCH, |
88 | NODE_TYPE_FUNCTION, |
89 | NODE_TYPE_COUNT, |
90 | } Kind; |
91 | union Union4 Data; |
92 | }; |
93 | |
94 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3) |
95 | struct TagWhereCountingEnumIsAliased { |
96 | enum { |
97 | tag_alias_counter1 = 1, |
98 | tag_alias_counter2 = 2, |
99 | tag_alias_counter3 = 3, |
100 | tag_alias_other_count = 3, |
101 | } Kind; |
102 | union { |
103 | char C; |
104 | short S; |
105 | int I; |
106 | long L; |
107 | } Data; |
108 | }; |
109 | |
110 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (2) |
111 | struct TagWithCountingEnumButOtherValueIsAliased { |
112 | enum { |
113 | tag_alias_other1 = 1, |
114 | tag_alias_other2 = 1, |
115 | tag_alias_other3 = 3, |
116 | tag_alias_other_count = 2, |
117 | } Kind; |
118 | union { |
119 | char C; |
120 | short S; |
121 | int I; |
122 | long L; |
123 | } Data; |
124 | }; |
125 | |
126 | // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3) |
127 | struct TagWhereCounterIsTheSmallest { |
128 | enum { |
129 | tag_large1 = 1000, |
130 | tag_large2 = 1001, |
131 | tag_large3 = 1002, |
132 | tag_large_count = 3, |
133 | } Kind; |
134 | union { |
135 | char C; |
136 | short S; |
137 | int I; |
138 | long L; |
139 | } Data; |
140 | }; |
141 | |
142 | // No warnings expected, only the last enum constant can be a counting enum constant |
143 | struct TagWhereCounterLikeNameIsNotLast { |
144 | enum { |
145 | kind_count, |
146 | kind2, |
147 | last_kind1, |
148 | kind3, |
149 | } Kind; |
150 | union { |
151 | char C; |
152 | short S; |
153 | int I; |
154 | long L; |
155 | } Data; |
156 | }; |
157 | |