Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access to the wrong field of aliased module #6726

Closed
vicuna opened this issue Dec 18, 2014 · 1 comment
Closed

Access to the wrong field of aliased module #6726

vicuna opened this issue Dec 18, 2014 · 1 comment
Assignees

Comments

@vicuna
Copy link

vicuna commented Dec 18, 2014

Original bug ID: 6726
Reporter: @chambart
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2016-12-07T10:37:16Z)
Resolution: fixed
Priority: normal
Severity: crash
Version: 4.03.0+dev / +beta1
Fixed in version: 4.03.0+dev / +beta1
Category: back end (clambda to assembly)
Monitored by: @gasche @yakobowski

Bug description

The problem was introduced by the commit 15405 "Fix #6465: allow incremental weakening of module aliases"

When compiling the example containing 3 files: extUnixAll.ml, extUnix.ml, test_endian_string.ml

ExtUnixAll.ml is

external unused : unit -> unit = "caml_blit_string"
module BigEndian = struct
let get_uint8 str off = 33
end

ExtUnix.ml is
module All = ExtUnixAll

test_endian_string.ml is
open ExtUnix.All
let test_endian_string x =
let module B = BigEndian in
B.get_uint8 x 0
let v = test_endian_string 1

The module ExtUnixAll compiles to this lambda code:

(seq
(seq
(let (get_uint8/1009 = (function str/1010 off/1011 33))
(setfield_imm 1 (global ExtUnixAll!) get_uint8/1009))
0a)
(let (BigEndian/1012 = (makeblock 0 (field 1 (global ExtUnixAll!))))
(seq (setfield_imm 0 (global ExtUnixAll!) BigEndian/1012) 0a)))

i.e. the module "BigEndian" is at field 0

With the trunk, test_string_endian compiles to:

(seq
(let
(test_endian_string/1201 =
(function x/1202
(let
(B/1204 = (let (let/1208 =a 0a) (field 1 (global ExtUnixAll!))))
(apply (field 0 B/1204) x/1202 0))))
(setfield_imm 0 (global Test_endian_string!) test_endian_string/1201))
(let (v/1205 = (apply (field 0 (global Test_endian_string!)) 1))
(setfield_imm 1 (global Test_endian_string!) v/1205))
0a)

i.e. it tries to access to the module at field 1

When looking at the typedtree, before 15405:

            Pexp_letmodule "B/1012"
            module_expr
              Pmod_ident "ExtUnix!.All.BigEndian"

after 15405:

            Pexp_letmodule "B/1204"
            module_expr
              module_expr
                Pmod_ident "ExtUnix!.All.BigEndian"

i.e. there is an additionnal Tmod_constraint.

My conclusion would be that the external in ExtUnixAll is considered as a regular function when coercing hence shifting the field access.

Steps to reproduce

ocamlc -c extUnixAll.ml
ocamlc -c extUnix.ml
ocamlc -c -no-alias-deps test_endian_string.ml
ocamlc -o test.byte extUnixAll.cmo test_endian_string.cmo
./test.byte

File attachments

@vicuna
Copy link
Author

vicuna commented Dec 19, 2014

Comment author: @garrigue

Fix in trunk at revision 15681.
Mtype.strengthen was not computing offsets correctly.
Should probably create a central point to solve this offset thing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants