aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cparser/Cutil.ml10
-rw-r--r--cparser/PackedStructs.ml2
-rw-r--r--cparser/StructReturn.ml6
-rw-r--r--cparser/Transform.ml33
-rw-r--r--cparser/Transform.mli6
-rw-r--r--cparser/Unblock.ml8
-rw-r--r--test/regression/Results/bitfields910
-rw-r--r--test/regression/bitfields9.c49
8 files changed, 105 insertions, 19 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index 4d6d2137..846010b3 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -964,8 +964,7 @@ let rec subst_stmt phi s =
| Sskip
| Sbreak
| Scontinue
- | Sgoto _
- | Sasm _ -> s.sdesc
+ | Sgoto _ -> s.sdesc
| Sdo e -> Sdo (subst_expr phi e)
| Sseq(s1, s2) -> Sseq (subst_stmt phi s1, subst_stmt phi s2)
| Sif(e, s1, s2) ->
@@ -981,6 +980,13 @@ let rec subst_stmt phi s =
| Sreturn (Some e) -> Sreturn (Some (subst_expr phi e))
| Sblock sl -> Sblock (List.map (subst_stmt phi) sl)
| Sdecl d -> Sdecl (subst_decl phi d)
+ | Sasm(attr, template, outputs, inputs, clob) ->
+ let subst_asm_operand (lbl, cstr, e) =
+ (lbl, cstr, subst_expr phi e) in
+ Sasm(attr, template,
+ List.map subst_asm_operand outputs,
+ List.map subst_asm_operand inputs,
+ clob)
}
diff --git a/cparser/PackedStructs.ml b/cparser/PackedStructs.ml
index 1f602fc1..ca6c9da5 100644
--- a/cparser/PackedStructs.ml
+++ b/cparser/PackedStructs.ml
@@ -317,7 +317,7 @@ let transf_expr loc env ctx e =
(* Statements *)
let transf_stmt env s =
- Transform.stmt transf_expr env s
+ Transform.stmt ~expr:transf_expr env s
(* Functions *)
diff --git a/cparser/StructReturn.ml b/cparser/StructReturn.ml
index 8bfc6954..660f1d9b 100644
--- a/cparser/StructReturn.ml
+++ b/cparser/StructReturn.ml
@@ -423,6 +423,7 @@ let transf_decl env (sto, id, ty, init) =
let transf_funbody env body optres =
let transf_expr ctx e = transf_expr env ctx e in
+let transf_asm_operand (lbl, cstr, e) = (lbl, cstr, transf_expr Val e) in
(* Function returns:
return kind scalar -> return e
@@ -484,7 +485,10 @@ let rec transf_stmt s =
{s with sdesc = Sblock(List.map transf_stmt sl)}
| Sdecl d ->
{s with sdesc = Sdecl(transf_decl env d)}
- | Sasm _ -> s
+ | Sasm(attr, template, outputs, inputs, clob) ->
+ {s with sdesc = Sasm(attr, template,
+ List.map transf_asm_operand outputs,
+ List.map transf_asm_operand inputs, clob)}
in
transf_stmt body
diff --git a/cparser/Transform.ml b/cparser/Transform.ml
index 3b6f10f6..6cdd8a6b 100644
--- a/cparser/Transform.ml
+++ b/cparser/Transform.ml
@@ -138,37 +138,46 @@ let expand_postincrdecr ~read ~write env ctx op l =
ecomma (eassign tmp (read l)) (ecomma (write l newval) tmp))
(* Generic transformation of a statement, transforming expressions within
- and preserving the statement structure. Applies only to unblocked code. *)
+ and preserving the statement structure.
+ If [decl] is not given, it applies only to unblocked code. *)
-let stmt trexpr env s =
+let stmt ~expr ?(decl = fun env decl -> assert false) env s =
let rec stm s =
match s.sdesc with
| Sskip -> s
| Sdo e ->
- {s with sdesc = Sdo(trexpr s.sloc env Effects e)}
+ {s with sdesc = Sdo(expr s.sloc env Effects e)}
| Sseq(s1, s2) ->
{s with sdesc = Sseq(stm s1, stm s2)}
| Sif(e, s1, s2) ->
- {s with sdesc = Sif(trexpr s.sloc env Val e, stm s1, stm s2)}
+ {s with sdesc = Sif(expr s.sloc env Val e, stm s1, stm s2)}
| Swhile(e, s1) ->
- {s with sdesc = Swhile(trexpr s.sloc env Val e, stm s1)}
+ {s with sdesc = Swhile(expr s.sloc env Val e, stm s1)}
| Sdowhile(s1, e) ->
- {s with sdesc = Sdowhile(stm s1, trexpr s.sloc env Val e)}
+ {s with sdesc = Sdowhile(stm s1, expr s.sloc env Val e)}
| Sfor(s1, e, s2, s3) ->
- {s with sdesc = Sfor(stm s1, trexpr s.sloc env Val e, stm s2, stm s3)}
+ {s with sdesc = Sfor(stm s1, expr s.sloc env Val e, stm s2, stm s3)}
| Sbreak -> s
| Scontinue -> s
| Sswitch(e, s1) ->
- {s with sdesc = Sswitch(trexpr s.sloc env Val e, stm s1)}
+ {s with sdesc = Sswitch(expr s.sloc env Val e, stm s1)}
| Slabeled(lbl, s) ->
{s with sdesc = Slabeled(lbl, stm s)}
| Sgoto lbl -> s
| Sreturn None -> s
| Sreturn (Some e) ->
- {s with sdesc = Sreturn(Some(trexpr s.sloc env Val e))}
- | Sasm _ -> s
- | Sblock _ | Sdecl _ ->
- assert false (* should not occur in unblocked code *)
+ {s with sdesc = Sreturn(Some(expr s.sloc env Val e))}
+ | Sasm(attr, template, outputs, inputs, clob) ->
+ let asm_operand (lbl, cstr, e) =
+ (lbl, cstr, expr s.sloc env Val e) in
+ {s with sdesc = Sasm(attr, template,
+ List.map asm_operand outputs,
+ List.map asm_operand inputs, clob)}
+ | Sblock sl ->
+ {s with sdesc = Sblock (List.map stm sl)}
+ | Sdecl d ->
+ {s with sdesc = Sdecl (decl env d)}
+
in stm s
(* Generic transformation of a function definition *)
diff --git a/cparser/Transform.mli b/cparser/Transform.mli
index 718a2f9c..57a4737b 100644
--- a/cparser/Transform.mli
+++ b/cparser/Transform.mli
@@ -50,8 +50,10 @@ val expand_postincrdecr :
(** Generic transformation of a statement *)
-val stmt : (C.location -> Env.t -> context -> C.exp -> C.exp) ->
- Env.t -> C.stmt -> C.stmt
+val stmt :
+ expr: (C.location -> Env.t -> context -> C.exp -> C.exp) ->
+ ?decl: (Env.t -> C.decl -> C.decl) ->
+ Env.t -> C.stmt -> C.stmt
(** Generic transformation of a function definition *)
diff --git a/cparser/Unblock.ml b/cparser/Unblock.ml
index 4013db9b..91f50552 100644
--- a/cparser/Unblock.ml
+++ b/cparser/Unblock.ml
@@ -225,7 +225,13 @@ let rec unblock_stmt env s =
{s with sdesc = Sreturn(Some (expand_expr true env e))}
| Sblock sl -> unblock_block env sl
| Sdecl d -> assert false
- | Sasm _ -> s
+ | Sasm(attr, template, outputs, inputs, clob) ->
+ let expand_asm_operand (lbl, cstr, e) =
+ (lbl, cstr, expand_expr true env e) in
+ {s with sdesc = Sasm(attr, template,
+ List.map expand_asm_operand outputs,
+ List.map expand_asm_operand inputs, clob)}
+
and unblock_block env = function
| [] -> sskip
diff --git a/test/regression/Results/bitfields9 b/test/regression/Results/bitfields9
new file mode 100644
index 00000000..ca74f1f4
--- /dev/null
+++ b/test/regression/Results/bitfields9
@@ -0,0 +1,10 @@
+glob_s = { a = -12, b = 1 }
+glob_t = { c = 123, d = 0, e = -45 }
+loc_s = { a = 11, b = 2 }
+loc_t = { c = 11, d = 1, e = 2 }
+compound_s = { a = 2, b = 3 }
+compound_t = { c = 2, d = 0, e = -11 }
+loc_s = { a = 7, b = 2 }
+loc_t = { c = 7, d = 1, e = 50 }
+compound_s = { a = -14, b = 3 }
+compound_t = { c = 50, d = 0, e = -7 }
diff --git a/test/regression/bitfields9.c b/test/regression/bitfields9.c
new file mode 100644
index 00000000..b33c4064
--- /dev/null
+++ b/test/regression/bitfields9.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+
+/* Initialization of bit-fields */
+
+struct s {
+ signed char a: 6;
+ unsigned int b: 2;
+};
+
+struct t {
+ unsigned int c: 16;
+ unsigned int d: 1;
+ short e: 8;
+};
+
+void print_s(char * msg, struct s p)
+{
+ printf("%s = { a = %d, b = %d }\n", msg, p.a, p.b);
+}
+
+void print_t(char * msg, struct t p)
+{
+ printf("%s = { c = %d, d = %d, e = %d }\n", msg, p.c, p.d, p.e);
+}
+
+/* Global initialization */
+struct s glob_s = { -12, 1 };
+struct t glob_t = { 123, 0, -45 };
+
+/* Local initialization */
+void f(int x, int y)
+{
+ struct s loc_s = { x, y };
+ struct t loc_t = { x, 1, y };
+ print_s("loc_s", loc_s);
+ print_t("loc_t", loc_t);
+ print_s("compound_s", (struct s) { y, x });
+ print_t("compound_t", (struct t) { y, 0, -x });
+}
+
+int main()
+{
+ print_s("glob_s", glob_s);
+ print_t("glob_t", glob_t);
+ f(11, 2);
+ f(7, 50);
+ return 0;
+}
+