1// RUN: %check_clang_tidy %s bugprone-tagged-union-member-count %t
2
3typedef enum Tags3 {
4 tags3_1,
5 tags3_2,
6 tags3_3,
7} Tags3;
8
9typedef enum Tags4 {
10 tags4_1,
11 tags4_2,
12 tags4_3,
13 tags4_4,
14} Tags4;
15
16typedef union Union3 {
17 short *Shorts;
18 int *Ints;
19 float *Floats;
20} Union3;
21
22typedef union Union4 {
23 short *Shorts;
24 double *Doubles;
25 int *Ints;
26 float *Floats;
27} Union4;
28
29// It is not obvious which enum is the tag for the union.
30struct maybeTaggedUnion1 { // No warnings expected.
31 enum Tags3 TagA;
32 enum Tags4 TagB;
33 union Union4 Data;
34};
35
36// It is not obvious which union does the tag belong to.
37struct maybeTaggedUnion2 { // No warnings expected.
38 enum Tags3 Tag;
39 union Union3 DataB;
40 union Union3 DataA;
41};
42
43// It is not obvious which union does the tag belong to.
44struct maybeTaggedUnion3 { // No warnings expected.
45 enum Tags3 Tag;
46 union {
47 int I1;
48 int I2;
49 int I3;
50 };
51 union {
52 float F1;
53 float F2;
54 float F3;
55 };
56};
57
58// No warnings expected, because LastATag is just an alias
59struct TaggedUnionWithAliasedEnumConstant {
60 enum {
61 ATag1,
62 ATag2,
63 ATag3,
64 LastATag = ATag3,
65 } Tag;
66 union {
67 float F;
68 int *Ints;
69 char Key[8];
70 } Data;
71};
72
73// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
74struct TaggedUnionStructWithPredefinedTagAndPredefinedUnion {
75 enum Tags3 Tag;
76 union Union4 Data;
77};
78
79// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
80struct TaggedUnionStructWithPredefinedTagAndInlineUnion {
81 enum Tags3 Tag;
82 union {
83 int *Ints;
84 char Characters[13];
85 struct {
86 double Re;
87 double Im;
88 } Complex;
89 long L;
90 } Data;
91};
92
93// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
94struct TaggedUnionStructWithInlineTagAndPredefinedUnion {
95 enum {
96 TaggedUnion7tag1,
97 TaggedUnion7tag2,
98 TaggedUnion7tag3,
99 } Tag;
100 union Union4 Data;
101};
102
103// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
104struct TaggedUnionStructWithInlineTagAndInlineUnion {
105 enum {
106 TaggedUnion8tag1,
107 TaggedUnion8tag2,
108 TaggedUnion8tag3,
109 } Tag;
110 union {
111 int *Ints;
112 char Characters[13];
113 struct {
114 double Re;
115 double Im;
116 } Complex;
117 long L;
118 } Data;
119};
120
121// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
122struct TaggedUnionStructNesting {
123 enum Tags3 Tag;
124 union {
125 float F;
126 int I;
127 long L;
128 // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: tagged union has more data members (4) than tags (3)
129 struct innerdecl {
130 enum Tags3 Tag;
131 union Union4 Data;
132 } Inner;
133 } Data;
134};
135
136// CHECK-MESSAGES: :[[@LINE+1]]:8: warning: tagged union has more data members (4) than tags (3)
137struct TaggedUnionStructWithTypedefedTagAndTypedefedUnion {
138 Tags3 Tag;
139 Union4 Data;
140};
141
142#define DECLARE_TAGGED_UNION_STRUCT(Tag, Union, Name)\
143struct Name {\
144 Tag Kind;\
145 Union Data;\
146}
147
148// CHECK-MESSAGES: :[[@LINE+1]]:44: warning: tagged union has more data members (4) than tags (3)
149DECLARE_TAGGED_UNION_STRUCT(Tags3, Union4, TaggedUnionStructFromMacro);
150

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.m