summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlasdair2018-07-05 21:34:23 +0100
committerAlasdair2018-07-05 21:36:23 +0100
commit79c9c884536cb522ac54c51aad70ab810ea4a420 (patch)
tree23769072f45d4623d6a55650d8ac7d99da9747b3 /src
parentb909248ac4599401312d121fc434f0520770454b (diff)
Fix equality comparisons for variants in C
Makes sure equality comparisons for variants are compiled correctly. Needed for CHERI and mips, which have structs containing variants. Also make sure that struct equality works for structs containing other structs.
Diffstat (limited to 'src')
-rw-r--r--src/c_backend.ml22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/c_backend.ml b/src/c_backend.ml
index 6097e996..09501ce9 100644
--- a/src/c_backend.ml
+++ b/src/c_backend.ml
@@ -2121,10 +2121,7 @@ let codegen_type_def ctx = function
in
let codegen_eq =
let codegen_eq_test (id, ctyp) =
- if is_stack_ctyp ctyp then
- string (Printf.sprintf "op1.%s == op2.%s" (sgen_id id) (sgen_id id))
- else
- string (Printf.sprintf "EQUAL(%s)(op1.%s, op2.%s)" (sgen_ctyp_name ctyp) (sgen_id id) (sgen_id id))
+ string (Printf.sprintf "EQUAL(%s)(op1.%s, op2.%s)" (sgen_ctyp_name ctyp) (sgen_id id) (sgen_id id))
in
string (Printf.sprintf "static bool EQUAL(%s)(struct %s op1, struct %s op2)" (sgen_id id) (sgen_id id) (sgen_id id))
^^ space
@@ -2245,6 +2242,21 @@ let codegen_type_def ctx = function
^^ each_ctor "op." set_field tus)
rbrace
in
+ let codegen_eq =
+ let codegen_eq_test ctor_id ctyp =
+ string (Printf.sprintf "return EQUAL(%s)(op1.%s, op2.%s);" (sgen_ctyp_name ctyp) (sgen_id ctor_id) (sgen_id ctor_id))
+ in
+ let rec codegen_eq_tests = function
+ | [] -> string "return false;"
+ | (ctor_id, ctyp) :: ctors ->
+ string (Printf.sprintf "if (op1.kind == Kind_%s && op2.kind == Kind_%s) " (sgen_id ctor_id) (sgen_id ctor_id)) ^^ lbrace ^^ hardline
+ ^^ jump 0 2 (codegen_eq_test ctor_id ctyp)
+ ^^ hardline ^^ rbrace ^^ string " else " ^^ codegen_eq_tests ctors
+ in
+ let n = sgen_id id in
+ string (Printf.sprintf "static bool EQUAL(%s)(struct %s op1, struct %s op2) " n n n)
+ ^^ surround 2 0 lbrace (codegen_eq_tests tus) rbrace
+ in
string (Printf.sprintf "// union %s" (string_of_id id)) ^^ hardline
^^ string "enum" ^^ space
^^ string ("kind_" ^ sgen_id id) ^^ space
@@ -2272,6 +2284,8 @@ let codegen_type_def ctx = function
^^ twice hardline
^^ codegen_setter
^^ twice hardline
+ ^^ codegen_eq
+ ^^ twice hardline
^^ separate_map (twice hardline) codegen_ctor tus
(* If this is the exception type, then we setup up some global variables to deal with exceptions. *)
^^ if string_of_id id = "exception" then