Skip to content

Commit 7bcca63

Browse files
mshinwelllthls
andauthored
Fix try region closure for "match with exception" under Flambda 2 (#1339)
Co-authored-by: Vincent Laviron <vincent.laviron@gmail.com>
1 parent b8dedd5 commit 7bcca63

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

middle_end/flambda2/from_lambda/lambda_to_flambda.ml

+27-12
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ module Function_decl = Closure_conversion_aux.Function_decls.Function_decl
2727
module Env : sig
2828
type t
2929

30-
type region_stack_element
30+
type region_stack_element = private
31+
| Regular of Ident.t
32+
| Try_with of Ident.t
33+
34+
val same_region : region_stack_element -> region_stack_element -> bool
3135

3236
val create :
3337
current_unit:Compilation_unit.t ->
@@ -152,7 +156,8 @@ module Env : sig
152156
(** Hack for staticfail (which should eventually use
153157
[pop_regions_up_to_context]) *)
154158
val pop_region :
155-
region_stack_element list -> (Ident.t * region_stack_element list) option
159+
region_stack_element list ->
160+
(region_stack_element * region_stack_element list) option
156161

157162
val pop_regions_up_to_context : t -> Continuation.t -> Ident.t option
158163

@@ -172,6 +177,12 @@ end = struct
172177
| Regular of Ident.t
173178
| Try_with of Ident.t
174179

180+
let same_region region1 region2 =
181+
match region1, region2 with
182+
| Regular _, Try_with _ | Try_with _, Regular _ -> false
183+
| Regular id1, Regular id2 | Try_with id1, Try_with id2 ->
184+
Ident.same id1 id2
185+
175186
type t =
176187
{ current_unit : Compilation_unit.t;
177188
current_values_of_mutables_in_scope :
@@ -407,7 +418,7 @@ end = struct
407418

408419
let pop_region = function
409420
| [] -> None
410-
| (Try_with region | Regular region) :: rest -> Some (region, rest)
421+
| ((Try_with _ | Regular _) as region) :: rest -> Some (region, rest)
411422

412423
let pop_regions_up_to_context t continuation =
413424
let initial_stack_context = region_stack_in_cont_scope t continuation in
@@ -535,32 +546,36 @@ let compile_staticfail acc env ccenv ~(continuation : Continuation.t) ~args :
535546
allocation region"
536547
Continuation.print continuation;
537548
let rec add_end_regions acc ~region_stack_now =
538-
(* CR pchambart: this probably can't be exercised right now, no lambda
539-
jumping through a region seems to be generated. *)
549+
(* This can maybe only be exercised right now using "match with exception",
550+
since that causes jumps out of try-regions (but not normal regions). *)
540551
(* CR pchambart: This closes all the regions between region_stack_now and
541552
region_stack_at_handler, but closing only the last one should be
542553
sufficient. *)
543-
let add_end_region region ~region_stack_now after_everything =
554+
let add_end_region (region : Env.region_stack_element) ~region_stack_now
555+
after_everything =
544556
let add_remaining_end_regions acc =
545557
add_end_regions acc ~region_stack_now
546558
in
547559
let body = add_remaining_end_regions acc after_everything in
548560
fun acc ccenv ->
549-
CC.close_let acc ccenv
550-
(Ident.create_local "unit")
551-
Not_user_visible Flambda_kind.With_subkind.tagged_immediate
552-
(End_region region) ~body
561+
match region with
562+
| Try_with _ -> body acc ccenv
563+
| Regular region_ident ->
564+
CC.close_let acc ccenv
565+
(Ident.create_local "unit")
566+
Not_user_visible Flambda_kind.With_subkind.tagged_immediate
567+
(End_region region_ident) ~body
553568
in
554569
let no_end_region after_everything = after_everything in
555570
match
556571
Env.pop_region region_stack_now, Env.pop_region region_stack_at_handler
557572
with
558573
| None, None -> no_end_region
559574
| Some (region1, region_stack_now), Some (region2, _) ->
560-
if Ident.same region1 region2
575+
if Env.same_region region1 region2
561576
then no_end_region
562577
else add_end_region region1 ~region_stack_now
563-
| Some (region, region_stack_now), None ->
578+
| Some (((Regular _ | Try_with _) as region), region_stack_now), None ->
564579
add_end_region region ~region_stack_now
565580
| None, Some _ -> assert false
566581
(* see above *)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(* TEST
2+
* native *)
3+
4+
let[@inline never] f x =
5+
local_ (x, (0, 0))
6+
7+
let[@inline never] g x =
8+
local_ (x, 0)
9+
10+
let[@inline never] h x =
11+
match f x with
12+
| exception Not_found -> 0
13+
| p ->
14+
(* The try-region must not have been closed, otherwise [p2] will
15+
clobber [p] *)
16+
let p2 = g x in
17+
(fst (snd p)) + fst p2
18+
19+
let () =
20+
Printf.printf "%d\n" (h 0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

0 commit comments

Comments
 (0)