summaryrefslogtreecommitdiffstats
path: root/test/Analysis/fields.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/fields.c')
-rw-r--r--test/Analysis/fields.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
index 12e8bbf..863a21a 100644
--- a/test/Analysis/fields.c
+++ b/test/Analysis/fields.c
@@ -29,6 +29,10 @@ void test() {
(void)(p = getit()).x;
}
+#define true ((bool)1)
+#define false ((bool)0)
+typedef _Bool bool;
+
void testLazyCompoundVal() {
Point p = {42, 0};
@@ -36,3 +40,86 @@ void testLazyCompoundVal() {
clang_analyzer_eval((q = p).x == 42); // expected-warning{{TRUE}}
clang_analyzer_eval(q.x == 42); // expected-warning{{TRUE}}
}
+
+
+struct Bits {
+ unsigned a : 1;
+ unsigned b : 2;
+ unsigned c : 1;
+
+ bool x;
+
+ struct InnerBits {
+ bool y;
+
+ unsigned d : 16;
+ unsigned e : 6;
+ unsigned f : 2;
+ } inner;
+};
+
+void testBitfields() {
+ struct Bits bits;
+
+ if (foo() && bits.b) // expected-warning {{garbage}}
+ return;
+ if (foo() && bits.inner.e) // expected-warning {{garbage}}
+ return;
+
+ bits.c = 1;
+ clang_analyzer_eval(bits.c == 1); // expected-warning {{TRUE}}
+
+ if (foo() && bits.b) // expected-warning {{garbage}}
+ return;
+ if (foo() && bits.x) // expected-warning {{garbage}}
+ return;
+
+ bits.x = true;
+ clang_analyzer_eval(bits.x == true); // expected-warning{{TRUE}}
+ bits.b = 2;
+ clang_analyzer_eval(bits.x == true); // expected-warning{{TRUE}}
+ if (foo() && bits.c) // no-warning
+ return;
+
+ bits.inner.e = 50;
+ if (foo() && bits.inner.e) // no-warning
+ return;
+ if (foo() && bits.inner.y) // expected-warning {{garbage}}
+ return;
+ if (foo() && bits.inner.f) // expected-warning {{garbage}}
+ return;
+
+ extern struct InnerBits getInner();
+ bits.inner = getInner();
+
+ if (foo() && bits.inner.e) // no-warning
+ return;
+ if (foo() && bits.inner.y) // no-warning
+ return;
+ if (foo() && bits.inner.f) // no-warning
+ return;
+
+ bits.inner.f = 1;
+
+ if (foo() && bits.inner.e) // no-warning
+ return;
+ if (foo() && bits.inner.y) // no-warning
+ return;
+ if (foo() && bits.inner.f) // no-warning
+ return;
+
+ if (foo() && bits.a) // expected-warning {{garbage}}
+ return;
+}
+
+
+//-----------------------------------------------------------------------------
+// Incorrect behavior
+//-----------------------------------------------------------------------------
+
+void testTruncation() {
+ struct Bits bits;
+ bits.c = 0x11; // expected-warning{{implicit truncation}}
+ // FIXME: We don't model truncation of bitfields.
+ clang_analyzer_eval(bits.c == 1); // expected-warning {{FALSE}}
+}
OpenPOWER on IntegriCloud