File tree 4 files changed +40
-7
lines changed
middle_end/flambda2/to_cmm
4 files changed +40
-7
lines changed Original file line number Diff line number Diff line change @@ -412,7 +412,15 @@ let can_raise_terminator (i : terminator) =
412
412
| Raise _ | Tailcall_func _ | Call _ | Prim { op = Probe _; label_after = _ }
413
413
->
414
414
true
415
- | Prim { op = External { alloc; _ } ; label_after = _ } -> alloc
415
+ | Prim { op = External { alloc; effects; _ } ; label_after = _ } ->
416
+ if not alloc then false
417
+ else (
418
+ (* Even if going via [caml_c_call], if there are no effects, the function
419
+ cannot raise an exception. (Example: [caml_obj_dup].) *)
420
+ match effects with
421
+ | No_effects -> false
422
+ | Arbitrary_effects -> true
423
+ )
416
424
| Specific_can_raise { op; _ } ->
417
425
assert (Arch. operation_can_raise op);
418
426
true
Original file line number Diff line number Diff line change @@ -858,7 +858,7 @@ let unary_primitive env res dbg f arg =
858
858
( None ,
859
859
res,
860
860
C. extcall ~dbg ~alloc: true ~returns: true ~is_c_builtin: false
861
- ~effects: Arbitrary_effects ~coeffects: Has_coeffects ~ty_args: []
861
+ ~effects: No_effects ~coeffects: Has_coeffects ~ty_args: []
862
862
" caml_obj_dup" Cmm. typ_val [arg] )
863
863
| Is_int _ -> None , res, C. and_int arg (C. int ~dbg 1 ) dbg
864
864
| Is_null -> None , res, C. eq ~dbg arg (C. nativeint ~dbg 0n )
Original file line number Diff line number Diff line change @@ -154,15 +154,20 @@ CAMLprim value caml_obj_with_tag(value new_tag_v, value arg)
154
154
tag_t tag_for_alloc ;
155
155
uintnat infix_offset = 0 ;
156
156
157
+ // This function must not raise exceptions (except asynchronous exceptions).
158
+
157
159
tag_t new_tag = (tag_t )Long_val (new_tag_v );
160
+ #ifdef DEBUG
158
161
tag_t existing_tag = Tag_val (arg );
162
+ #endif
159
163
160
- if ((existing_tag == Closure_tag || existing_tag == Infix_tag
164
+ CAMLassert (
165
+ !(
166
+ (existing_tag == Closure_tag || existing_tag == Infix_tag
161
167
|| new_tag == Closure_tag || new_tag == Infix_tag )
162
- && existing_tag != new_tag ) {
163
- caml_failwith ("Cannot change tags of existing closures or create \
164
- new closures using [caml_obj_with_tag]" );
165
- }
168
+ && existing_tag != new_tag ));
169
+ // Cannot change tags of existing closures or create new closures using
170
+ // [caml_obj_with_tag].
166
171
167
172
if (new_tag == Infix_tag ) {
168
173
// If we received an infix block, we must return the same; but the whole
Original file line number Diff line number Diff line change
1
+ (* TEST *)
2
+
3
+ [@@@ ocaml.flambda_o3]
4
+
5
+ let [@ inline never] bar _ _ = ()
6
+
7
+ let [@ inline never] baz () = ()
8
+
9
+ let foo size (x : int ) arr y =
10
+ let extra_arg_array = ref arr in
11
+ let extra_arg_int = ref 0 in
12
+ (try
13
+ for i = 0 to size - 1 do
14
+ if i > 20 then (
15
+ let _ = Sys. opaque_identity (Obj. dup y) in
16
+ baz ()
17
+ )
18
+ done
19
+ with _exn -> () );
20
+ bar ! extra_arg_array ! extra_arg_int
You can’t perform that action at this time.
0 commit comments