diff options
Diffstat (limited to 'test/Analysis/fields.c')
-rw-r--r-- | test/Analysis/fields.c | 87 |
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}} +} |