Skip to content

Ephemerons do not correctly handle Infix_tag #7810

@vicuna

Description

@vicuna

Original bug ID: 7810
Reporter: @stedolan
Status: new
Resolution: open
Priority: normal
Severity: minor
Category: runtime system and C interface

Bug description

This function creates an ephemeron, fills it in, causes a GC and finally inspects the ephemeron. The ephemeron should not be cleared because the key is still live, since it is part of the return value.

let ephe x =
  let open Ephemeron.K1 in
  let e = create () in
  set_key e x;
  set_data e 42;
  Gc.full_major ();
  (x, get_data e)

The second component of this pair should never be None, e.g.:

# ephe (ref 1000);;
- : int ref * int option = ({contents = 1000}, Some 42)

However, it is None if the argument has Infix_tag (i.e. is a member of a set of mutually recursive functions other than the first):

# ephe (let rec f x = () and g x = () in g);;
Warning 26: unused variable f.
- : ('_a -> unit) * int option = (<fun>, None)

The bug is this check in minor_gc.c (which appears a couple of times):

if (Hd_val (*key) == 0){ /* Value copied to major heap */

If *key has Infix_tag, Hd_val (*key) can be nonzero even though it is copied to the major heap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions