@@ -99,8 +99,9 @@ let translate_builtin_typ (t: Clang__Clang__ast.builtin_type) = match t with
9999 | ULongLong -> failwith " translate_builtin_typ: ulonglong"
100100 | UInt128 -> failwith " translate_builtin_typ: uint128"
101101
102+ | Int -> TInt Int32 (* TODO: Retrieve exact width *)
103+
102104 | Short
103- | Int
104105 | Long
105106 | LongLong
106107 | Int128 -> failwith " translate_builtin_typ: signed int"
@@ -142,6 +143,15 @@ let rec translate_typ (typ: qual_type) = match typ.desc with
142143(* Takes a Clangml expression [e], and retrieves the corresponding karamel Ast type *)
143144let typ_of_expr (e : expr ) : typ = Clang.Type. of_node e |> translate_typ
144145
146+ (* Check whether a given Clang expression is a memcpy callee *)
147+ let is_memcpy (e : expr ) = match e.desc with
148+ | DeclRef { name; _ } ->
149+ let name = get_id_name name in
150+ name = " __builtin___memcpy_chk"
151+ | _ -> false
152+
153+
154+
145155(* Translate expression [e], with expected type [t] *)
146156let rec translate_expr ' (env : env ) (t : typ ) (e : expr ) : expr' = match e.desc with
147157 | IntegerLiteral (Int n ) -> EConstant (Helpers. assert_tint t, string_of_int n)
@@ -168,7 +178,8 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
168178 let lhs_ty = typ_of_expr lhs in
169179 let lhs = translate_expr env (typ_of_expr lhs) lhs in
170180 let rhs = translate_expr env (typ_of_expr rhs) rhs in
171- let rhs = Ast. with_type TUnit (EAssign (lhs, Ast. with_type lhs_ty (EApp (assign_to_bop kind, [lhs; rhs])))) in
181+ (* Rewrite the rhs into the compound expression, using the underlying operator *)
182+ let rhs = Ast. with_type lhs_ty (EApp (assign_to_bop kind, [lhs; rhs])) in
172183 begin match lhs.node with
173184 (* Special-case rewriting for buffer assignments *)
174185 | EBufRead (base , index ) -> EBufWrite (base, index, rhs)
@@ -188,10 +199,29 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
188199
189200 | DeclRef {name; _} -> get_id_name name |> find_var env
190201
202+ | Call {callee; args} when is_memcpy callee ->
203+ (* Format.printf "Trying to translate memcpy %a@." Clang.Expr.pp e; *)
204+ begin match args with
205+ (* We are assuming here that this is __builtin___memcpy_chk.
206+ This function has a fourth argument, corresponding to the number of bytes
207+ remaining in dst. We omit it during the translation *)
208+ | [dst; src; len; _] ->
209+ let dst = translate_expr env (typ_of_expr dst) dst in
210+ let src = translate_expr env (typ_of_expr src) src in
211+ begin match len.desc with
212+ | BinaryOperator {lhs; kind = Mul ; rhs = { desc = UnaryExpr {kind = SizeOf ; _} ; _} } ->
213+ let len = translate_expr env Helpers. usize lhs in
214+ EBufBlit (src, Helpers. zerou32, dst, Helpers. zerou32, len)
215+ | _ -> failwith " ill-formed memcpy"
216+ end
217+ | _ -> failwith " memcpy does not have the right number of arguments"
218+ end
219+
191220 | Call {callee; args} ->
192221 (* In C, a function type is a pointer. We need to strip it to retrieve
193222 the standard arrow abstraction *)
194223 let fun_typ = Helpers. assert_tbuf (typ_of_expr callee) in
224+ (* Format.printf "Trying to translate function call %a@." Clang.Expr.pp callee; *)
195225 let callee = translate_expr env fun_typ callee in
196226 let args = List. map (fun x -> translate_expr env (typ_of_expr x) x) args in
197227 EApp (callee, args)
@@ -210,9 +240,10 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
210240
211241 | ConditionalOperator _ -> failwith " translate_expr: conditional operator"
212242 | Paren _ -> failwith " translate_expr: paren"
213- | SizeOfPack _ -> failwith " translate_expr: size_of"
214243
215- | _ -> failwith " translate_expr: unsupported expression"
244+ | _ ->
245+ Format. printf " Trying to translate expression %a@." Clang.Expr. pp e;
246+ failwith " translate_expr: unsupported expression"
216247
217248and translate_expr (env : env ) (t : typ ) (e : expr ) : Ast.expr =
218249 Ast. with_type t (translate_expr' env t e)
@@ -254,7 +285,8 @@ let rec translate_stmt' (env: env) (t: typ) (s: stmt_desc) : expr' = match s wit
254285 (* The do statements first executes the body before behaving as a while loop.
255286 We thus translate it as a sequence of the body and the corresponding while loop *)
256287 let body = translate_stmt env t body.desc in
257- let cond = translate_expr env TBool cond in
288+ (* TODO: Likely need to translate int conditions to boolean expressions *)
289+ let cond = translate_expr env (typ_of_expr cond) cond in
258290 ELet (
259291 Helpers. sequence_binding () ,
260292 body,
0 commit comments