Fix tail-call optimisation with a mutable ref
(Clet_mutable was not recognized properly in tail position.)
Add a test for tail-call optimisation with a mutable ref
In recent FreeBSD, `cc` is Clang and `ld` is LLD, the LLVM linker, but
`as` is still GNU binutils. Moreover, Clang contains its own
assembler and does not call `as`. Consequently, object files produced
by invoking `as` directly are slightly different from those produced
by `cc`.
This can cause obscure errors such as issue #9068: `ld -r` fails when
combining objects produced by `as` and objects produced by `cc`.
The workaround is to use `cc` as the assembler. We already did that
for the ARM and ARM64 targets, but #9068 shows that it is necessary
for AMD64 too. Just use `cc` as assembler for all FreeBSD targets.
Similar issues were reported under Linux when clang and LLD are used
instead of GCC and binutils. We already used clang as the preprocessed
assembler in this case. Also use clang as the assembler in this case.
Closes: #9068
This option forces GCC to follow the ISO C standards concerning
rounding of intermediate FP results. It avoids some FP issues
with the x86 32 bits ports of OCaml, which can run into
excess precision problems due to the x87 FP unit.
Closes: #7917
This commit reverts c1a7ace (originally c545e04), which was a
temporary fix that is no longer needed because it was superseded by
#6608.
The temporary fix caused `{expr with lbl1 = e1; ... }` to not evaluate
`expr` if all labels of its type are overriden. As reported in #7696
this is not desirable. Reverting the temporary fix causes `expr` to
be evaluated always.
As a consequence, a corner case of value "let rec" is no longer accepted.
The corresponding test was updated.
Closes: #7696
This commit changes caml_output_value_to_malloc to use the same
pattern as caml_output_val and caml_output_value_to_bytes:
the blocks of output are freed in the same loop that copies
them to the final destination.
Originally, caml_output_value_to_malloc calls free_extern_output
to free the blocks of output. This is correct too, but causes
extern_free_stack to be called twice, once at the end of extern_value
and once in free_extern_output. This is OK because extern_free_stack
is protected against double free errors.
Still, I find it more elegant, more consistent with the rest of the
code, and less error-prone w.r.t. double free errors to not call
free_extern_output at the end of caml_output_value_to_malloc.
Later, free_extern_output could be renamed to e.g. extern_finalize
to emphasize that it is to be called when something goes wrong and
we are about to raise an exception.
In the original code, if `caml_output_value_to_block` raises an exception,
`free_extern_output` does not call `extern_free_stack` because
of the early return on `extern_userprovided_output != NULL`.
Fix the name of the field `isnode` in the struct `large_free_block` in the comment documenting it (was `node` before).
Replace "son" by "child" in the documentation of the struct "large_free_block".
review of can_group factorization by @gasche:
> I reviewed the change to `can_group` and believe it is correct.
> (I knew it would be nicer as a binary operation!)
>
> The different treatments of Lazy and Tuple/Record does look a bit odd,
> but I believe that it is actually the right thing to write.
>
> In the Tuple or Record case, the idea is that we can group Any heads
> with the Tuple/Record case and just explode all of them (including the
> Any cases) according to the tuple/record arity.
>
> In the Lazy case, the corresponding choice would be to add Any values
> to the Lazy group, and force all the elements of the group. This is
> not so nice, because intuitively we shouldn't force Lazy values unless
> we have to.
>
> One may expect that in general the argument of the pattern will be
> forced anyway, as long as there is at least one Lazy pattern above in
> the matrix, so it doesn't really matter whether we include the Any
> patterns in the forced group or not. I would argue that (1) even if
> that was true, it would be semantically dubious to handle Any that way
> (see a more precise criterion below), (2) I am not actually sure that
> this is true, what if the first group gets found unreachable by
> splits in following columns?
>
> # type void = | ;;
> # match (lazy (print_endline "foo"), (None : void option)) with
> | lazy (), Some _ -> .
> | _, None -> false;;
> - : bool = false
>
> This gives the following decision tree for whether Any is included in
> the group:
>
> - Can the absence of Any be used to generate nice/efficient tests for
> the heads of the group? In that case, don't include Any.
> (Not included: all the Constant cases, Array (discriminate on size),
> String, etc.)
>
> - Is Any always exactly equivalent to a more-defined head for values
> of this type? In that case, do include Any, otherwise do not.
> (Included: Variant, Record)
> (Not included: Lazy)