Skip to content

Commit 6504c96

Browse files
authored
[clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field (#145066)
For the following code in C mode: https://godbolt.org/z/3eo1MeGhe (There is no warning in C++ mode though). ```c++ struct B { int i : 2; int : 30; // unnamed bit-field }; extern void consume_B(struct B); void bitfield_B_init(void) { struct B b1; b1.i = 1; // b1 is initialized consume_B(b1); // FP: Passed-by-value struct argument contains uninitialized data (e.g., field: '') [core.CallAndMessage] } ```
1 parent 1f8f477 commit 6504c96

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ class FindUninitializedField {
253253
const RecordDecl *RD = RT->getDecl()->getDefinition();
254254
assert(RD && "Referred record has no definition");
255255
for (const auto *I : RD->fields()) {
256+
if (I->isUnnamedBitField())
257+
continue;
256258
const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
257259
FieldChain.push_back(I);
258260
T = I->getType();

clang/test/Analysis/call-and-message.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
// RUN: %clang_analyze_cc1 %s -verify \
22
// RUN: -analyzer-checker=core \
33
// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=true \
4+
// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false \
45
// RUN: -analyzer-output=plist -o %t.plist
56
// RUN: cat %t.plist | FileCheck %s
67

78
// RUN: %clang_analyze_cc1 %s -verify=no-pointee \
89
// RUN: -analyzer-checker=core \
9-
// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false
10+
// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
11+
// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false
12+
13+
// RUN: %clang_analyze_cc1 %s -verify=arg-init \
14+
// RUN: -analyzer-checker=core \
15+
// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
16+
// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=true
1017

1118
// no-pointee-no-diagnostics
1219

@@ -22,3 +29,21 @@ void pointee_uninit(void) {
2229
// checker, as described in the CallAndMessage comments!
2330
// CHECK: <key>issue_hash_content_of_line_in_context</key>
2431
// CHECK-SAME: <string>97a74322d64dca40aa57303842c745a1</string>
32+
33+
typedef struct {
34+
int i :2;
35+
int :30; // unnamed bit-field
36+
} B;
37+
38+
extern void consume_B(B);
39+
40+
void bitfield_B_init(void) {
41+
B b1;
42+
b1.i = 1; // b1 is initialized
43+
consume_B(b1);
44+
}
45+
46+
void bitfield_B_uninit(void) {
47+
B b2;
48+
consume_B(b2); // arg-init-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'i') [core.CallAndMessage]}}
49+
}

clang/test/Analysis/call-and-message.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,20 @@ void record_uninit() {
169169
// CHECK-SAME: <string>a46bb5c1ee44d4611ffeb13f7f499605</string>
170170
// CHECK: <key>issue_hash_content_of_line_in_context</key>
171171
// CHECK-SAME: <string>e0e0d30ea5a7b2e3a71e1931fa0768a5</string>
172+
173+
struct B{
174+
int i :2;
175+
int :30; // unnamed bit-field
176+
};
177+
178+
void bitfield_B_init(void) {
179+
B b1;
180+
b1.i = 1; // b1 is initialized
181+
consume(b1);
182+
}
183+
184+
void bitfield_B_uninit(void) {
185+
B b2;
186+
consume(b2); // arg-init-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'i') [core.CallAndMessage]}}
187+
}
172188
} // namespace uninit_arg

0 commit comments

Comments
 (0)