aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-02-27 10:27:49 +0100
committerChristopher Li <sparse@chrisli.org>2017-03-04 00:45:38 +0800
commit522773d089700cce5551860aea3cb93f40b5f3a4 (patch)
tree815d74e8bb097518194f53707d7f1260800a27ae /validation
parentb8c268640114d614178d4875fbe0f5e6b53b036b (diff)
downloadsparse-dev-522773d089700cce5551860aea3cb93f40b5f3a4.tar.gz
fix size of loaded bitfields
Loading a bitfield correctly take in account the offset of the bitfield inside the whole container integer. But truncating it to the width of the bitfield is not done or is done very implicitely (because the correct size is not lost). For example, with the following code: struct bfu { unsigned int a:3; }; unsigned int get__bfu_a(struct bfu bf) { return bf.a; } test-linearize gives as output something like: get__bfu_a: cast.32 %r2 <- (3) %arg1 ret.32 %r2 We can notice the (3) in the cast instruction but this is misleading as %arg1 is not 3bit wide. Fix this by adding the missing truncating cast. This will then gives something like: get__bfu_a: cast.3 %r2 <- (32) %arg1 cast.32 %r3 <- (3) %r2 ret.32 %r3 Note the truncation could also be done by a and-mask but the cast is more logical since we're here only changing size and not doing some arithmetic operations. Fixes: 1688f039c ("Re-do memory access linearization.") Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'validation')
-rw-r--r--validation/bitfield-size.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/validation/bitfield-size.c b/validation/bitfield-size.c
new file mode 100644
index 00000000..ce78ecf2
--- /dev/null
+++ b/validation/bitfield-size.c
@@ -0,0 +1,41 @@
+struct bfu {
+ unsigned int a:4;
+ unsigned int :2;
+ unsigned int b:4;
+};
+unsigned int get__bfu_a(struct bfu bf) { return bf.a; }
+unsigned int get__bfu_b(struct bfu bf) { return bf.b; }
+unsigned int get_pbfu_a(struct bfu *bf) { return bf->a; }
+unsigned int get_pbfu_b(struct bfu *bf) { return bf->b; }
+
+
+struct bfs {
+ signed int a:4;
+ signed int :2;
+ signed int b:4;
+};
+signed int get__bfs_a(struct bfs bf) { return bf.a; }
+signed int get__bfs_b(struct bfs bf) { return bf.b; }
+signed int get_pbfs_a(struct bfs *bf) { return bf->a; }
+signed int get_pbfs_b(struct bfs *bf) { return bf->b; }
+
+
+struct bfi {
+ int a:4;
+ int :2;
+ int b:4;
+};
+unsigned int get__bfi_a(struct bfi bf) { return bf.a; }
+unsigned int get__bfi_b(struct bfi bf) { return bf.b; }
+unsigned int get_pbfi_a(struct bfi *bf) { return bf->a; }
+unsigned int get_pbfi_b(struct bfi *bf) { return bf->b; }
+
+/*
+ * check-name: bitfield size
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-pattern-24-times: cast\\.
+ * check-output-pattern-12-times: cast\\.4
+ * check-output-pattern-6-times: lsr\\..*\\$6
+ */