@@ -113,6 +113,102 @@ void testBitfields(void) {
113113}
114114
115115
116+ struct BitfieldUnion {
117+ union {
118+ struct {
119+ unsigned int addr : 22 ;
120+ unsigned int vf : 1 ;
121+ };
122+ unsigned int raw ;
123+ };
124+ };
125+
126+ struct BitfieldUnion processBitfieldUnion (struct BitfieldUnion r ) {
127+ struct BitfieldUnion result = r ;
128+ result .addr += 1 ;
129+ return result ;
130+ }
131+
132+ void testBitfieldUnionCompoundLiteral (void ) {
133+ struct BitfieldUnion r1 = processBitfieldUnion ((struct BitfieldUnion ){.addr = 100 , .vf = 1 });
134+ clang_analyzer_eval (r1 .addr == 101 ); // expected-warning{{TRUE}}
135+ clang_analyzer_eval (r1 .vf == 1 ); // expected-warning{{UNKNOWN}}
136+
137+ struct BitfieldUnion r2 = processBitfieldUnion ((struct BitfieldUnion ){.addr = 1 });
138+ clang_analyzer_eval (r2 .addr == 2 ); // expected-warning{{TRUE}}
139+ clang_analyzer_eval (r2 .vf ); // expected-warning{{UNKNOWN}}
140+ }
141+
142+ struct NestedBitfields {
143+ struct {
144+ unsigned x : 16 ;
145+ unsigned y : 16 ;
146+ } inner ;
147+ };
148+
149+ struct NestedBitfields processNestedBitfields (struct NestedBitfields n ) {
150+ struct NestedBitfields tmp = n ;
151+ tmp .inner .x += 1 ;
152+ return tmp ;
153+ }
154+
155+ void testNestedBitfields (void ) {
156+ struct NestedBitfields n1 = processNestedBitfields ((struct NestedBitfields ){.inner .x = 1 });
157+ clang_analyzer_eval (n1 .inner .x == 2 ); // expected-warning{{TRUE}}
158+ clang_analyzer_eval (n1 .inner .y == 0 ); // expected-warning{{TRUE}}
159+
160+ struct NestedBitfields n2 = processNestedBitfields ((struct NestedBitfields ){{200 , 300 }});
161+ clang_analyzer_eval (n2 .inner .x == 201 ); // expected-warning{{TRUE}}
162+ clang_analyzer_eval (n2 .inner .y == 300 ); // expected-warning{{TRUE}}
163+ }
164+
165+ struct UnionContainerBitfields {
166+ union {
167+ unsigned val ;
168+ struct {
169+ unsigned x : 16 ;
170+ unsigned y : 16 ;
171+ };
172+ } u ;
173+ };
174+
175+ struct UnionContainerBitfields processUnionContainer (struct UnionContainerBitfields c ) {
176+ struct UnionContainerBitfields tmp = c ;
177+ tmp .u .x += 1 ;
178+ return tmp ;
179+ }
180+
181+ void testUnionContainerBitfields (void ) {
182+ struct UnionContainerBitfields c1 = processUnionContainer ((struct UnionContainerBitfields ){.u .val = 100 });
183+ clang_analyzer_eval (c1 .u .x == 101 ); // expected-warning{{FALSE}} // expected-warning{{TRUE}}
184+
185+ struct UnionContainerBitfields c2 = processUnionContainer ((struct UnionContainerBitfields ){.u .x = 100 });
186+ clang_analyzer_eval (c2 .u .x == 101 ); // expected-warning{{TRUE}}
187+ }
188+
189+ struct MixedBitfields {
190+ unsigned char x ;
191+ unsigned y : 12 ;
192+ unsigned z : 20 ;
193+ };
194+
195+ struct MixedBitfields processMixedBitfields (struct MixedBitfields m ) {
196+ struct MixedBitfields tmp = m ;
197+ tmp .y += 1 ;
198+ return tmp ;
199+ }
200+
201+ void testMixedBitfields (void ) {
202+ struct MixedBitfields m1 = processMixedBitfields ((struct MixedBitfields ){.x = 100 , .y = 100 });
203+ clang_analyzer_eval (m1 .x == 100 ); // expected-warning{{TRUE}}
204+ clang_analyzer_eval (m1 .y == 101 ); // expected-warning{{TRUE}}
205+
206+ struct MixedBitfields m2 = processMixedBitfields ((struct MixedBitfields ){.z = 100 });
207+ clang_analyzer_eval (m2 .y == 1 ); // expected-warning{{TRUE}}
208+ clang_analyzer_eval (m2 .z == 100 ); // expected-warning{{TRUE}}
209+ }
210+
211+
116212//-----------------------------------------------------------------------------
117213// Incorrect behavior
118214//-----------------------------------------------------------------------------
0 commit comments