···64646565### Internal/compiler-libs changes:
66666767+- #1599: add unset directive to ocamltest to clear environment variables before
6868+ running tests.
6969+ (David Allsopp, review by Damien Doligez and Sébastien Hinderer)
7070+6771- #10433: Remove the distinction between 32-bit aligned and 64-bit aligned
6872 64-bit floats in Cmm.memory_chunk.
6973 (Greta Yorsh, review by Xavier Leroy)
···84888589### Build system:
86909191+- #10471: Fix detection of arm32 architectures with musl in the configure
9292+ script.
9393+ (Louis Gesbert)
9494+8795### Bug fixes:
88968997- #10473: Add CFI directives to RISC-V runtime and asmcomp.
···96104 otherwise the derived pointer is live across a poll point.
97105 (Vincent Laviron and Xavier Leroy, review by Xavier Leroy and Sadiq Jaffer)
98106107107+- #10542: Fix detection of immediate64 types through unboxed types.
108108+ (Leo White, review by Stephen Dolan and Gabriel Scherer)
99109100110OCaml 4.13.0
101111-------------
···534544535545- #10307: Make build_other_constrs work with names instead of tags.
536546 (Nicolas Chataing, review by Florian Angeletti)
547547+548548+- #10543: Fix Ast_mapper to apply the mapping function to the constants in
549549+ "interval" patterns `c1..c2`.
550550+ (Guillaume Petiot, review by Gabriel Scherer and Nicolás Ojeda Bär)
537551538552### Build system:
539553
-4
INSTALL.adoc
···164164 the C locale (`export LC_ALL=C`) before compiling if you have strange errors
165165 while compiling OCaml.
166166167167-* On HP 9000/700 machines under HP/UX 9, some versions of `cc` are unable to
168168- compile correctly the runtime system (wrong code is generated for `(x - y)`
169169- where `x` is a pointer and `y` an integer). Fix: use `gcc`.
170170-171167* In the unlikely case that a platform does not offer all C99 float operations
172168 that the runtime needs, a configuration error will result. Users
173169 can work around this problem by calling `configure` with the flag
···779779 in \ref{sss:ocamldoc-target-specific-syntax}) \\
780780@||@&@ '{!' string '}' @ & insert a cross-reference to an element
781781 (see section \ref{sss:ocamldoc-crossref} for the syntax of cross-references).\\
782782+@||@&@ '{{!' string '}' inline-text '}' @ & insert a cross-reference with the given text. \\
782783@||@&@ '{!modules:' string string ... '}' @ & insert an index table
783784for the given module names. Used in HTML only.\\
784785@||@&@ '{!indexlist}' @ & insert a table of links to the various indexes
···136136 (regexp (">[0-9]+\\.\\([0-9]+\\)" ^ preg_anyspace)))
137137 {|><span class="number">\1</span>|}
138138 |> Re.Str.(global_replace
139139- (regexp ("[0-9]+\\.\\([0-9]+\\.[0-9]+\\)" ^ preg_anyspace)))
139139+ (regexp ("[0-9]+\\.\\([0-9]+\\(\\.[0-9]+\\)+\\)" ^ preg_anyspace)))
140140 {|<span class="number">\1</span>|}
141141142142 (* The API (libref and compilerlibref directories) should be separate
+11
manual/src/refman/modtypes.etex
···262262particular, a functor may take another functor as argument
263263(``higher-order'' functor).
264264265265+When the result module type is itself a functor,
266266+\begin{center}
267267+@'functor' '(' name_1 ':' module-type_1 ')' '->' \ldots '->'
268268+ 'functor' '(' name_n ':' module-type_n ')' '->' module-type@
269269+\end{center}
270270+one may use the abbreviated form
271271+\begin{center}
272272+@'functor' '(' name_1 ':' module-type_1 ')' \ldots
273273+ '(' name_n ':' module-type_n ')' '->' module-type@
274274+\end{center}
275275+265276\subsection{ss:mty-with}{The "with" operator}
266277267278\ikwd{with\@\texttt{with}}
+11
manual/src/refman/modules.etex
···228228functor argument; in particular, a functor may take another functor as
229229argument (``higher-order'' functor).
230230231231+When the result module expression is itself a functor,
232232+\begin{center}
233233+@'functor' '(' name_1 ':' module-type_1 ')' '->' \ldots '->'
234234+ 'functor' '(' name_n ':' module-type_n ')' '->' module-expr@
235235+\end{center}
236236+one may use the abbreviated form
237237+\begin{center}
238238+@'functor' '(' name_1 ':' module-type_1 ')' \ldots
239239+ '(' name_n ':' module-type_n ')' '->' module-expr@
240240+\end{center}
241241+231242\subsubsection*{sss:mexpr-functor-app}{Functor application}
232243233244The expression @module-expr_1 '(' module-expr_2 ')'@ evaluates
+2-2
ocamltest/actions_helpers.ml
···160160 log_redirection "stdout" stdout_filename;
161161 log_redirection "stderr" stderr_filename;
162162 let systemenv =
163163- Array.append
163163+ Environments.append_to_system_env
164164 environment
165165- (Environments.to_system_env env)
165165+ env
166166 in
167167 let timeout =
168168 match timeout with
+48-8
ocamltest/environments.ml
···19192020module VariableMap = Map.Make (Variables)
21212222-type t = string VariableMap.t
2222+type t = string option VariableMap.t
23232424let empty = VariableMap.empty
25252626let to_bindings env =
2727- let f variable value lst = (variable, value) :: lst in
2727+ let f variable value lst =
2828+ Option.fold ~none:lst ~some:(fun value -> (variable, value) :: lst) value
2929+ in
2830 VariableMap.fold f env []
29313032let expand_aux env value =
···3941 let expanded = expand_aux env value in
4042 if expanded=value then value else expand env expanded
41434242-let to_system_env env =
4444+let expand env = function
4545+ | None -> raise Not_found
4646+ | Some value -> expand env value
4747+4848+let append_to_system_env environment env =
4949+ (* Augment env with any bindings which are only in environment. This must be
5050+ done here as the Windows C implementation doesn't process multiple values
5151+ in settings.envp. *)
5252+ let env =
5353+ let update env binding =
5454+ let name, value =
5555+ match String.index binding '=' with
5656+ | c ->
5757+ let name = String.sub binding 0 c in
5858+ let value =
5959+ String.sub binding (c + 1) (String.length binding - c - 1) in
6060+ (name, Some value)
6161+ | exception Not_found ->
6262+ (binding, None)
6363+ in
6464+ let var = Variables.make (name, "system env var") in
6565+ if not (VariableMap.mem var env) then
6666+ VariableMap.add var value env
6767+ else
6868+ env
6969+ in
7070+ Array.fold_left update env environment
7171+ in
4372 let system_env = Array.make (VariableMap.cardinal env) "" in
4473 let i = ref 0 in
4574 let store variable value =
7575+ let some value =
7676+ Variables.string_of_binding variable (expand env (Some value)) in
4677 system_env.(!i) <-
4747- Variables.string_of_binding variable (expand env value);
7878+ Option.fold ~none:(Variables.name_of_variable variable) ~some value;
4879 incr i in
4980 VariableMap.iter store env;
5081 system_env
8282+8383+let to_system_env env =
8484+ append_to_system_env [||] env
51855286let lookup variable env =
5387 try Some (expand env (VariableMap.find variable env)) with Not_found -> None
···75109let is_variable_defined variable env =
76110 VariableMap.mem variable env
771117878-let add variable value env = VariableMap.add variable value env
112112+let add variable value env = VariableMap.add variable (Some value) env
7911380114let add_if_undefined variable value env =
81115 if VariableMap.mem variable env then env else add variable value env
···83117let append variable appened_value environment =
84118 let previous_value = safe_lookup variable environment in
85119 let new_value = previous_value ^ appened_value in
8686- VariableMap.add variable new_value environment
120120+ VariableMap.add variable (Some new_value) environment
8712188122let remove = VariableMap.remove
123123+124124+let unsetenv variable environment =
125125+ VariableMap.add variable None environment
8912690127let add_bindings bindings env =
91128 let f env (variable, value) = add variable value env in
···9313094131let from_bindings bindings = add_bindings bindings empty
951329696-let dump_assignment log (variable, value) =
9797- Printf.fprintf log "%s = %s\n%!" (Variables.name_of_variable variable) value
133133+let dump_assignment log = function
134134+ | (variable, Some value) ->
135135+ Printf.fprintf log "%s = %s\n%!" (Variables.name_of_variable variable) value
136136+ | (variable, None) ->
137137+ Printf.fprintf log "unsetenv %s\n%!" (Variables.name_of_variable variable)
9813899139let dump log environment =
100140 List.iter (dump_assignment log) (VariableMap.bindings environment)
+5
ocamltest/environments.mli
···2222val from_bindings : (Variables.t * string) list -> t
2323val to_bindings : t -> (Variables.t * string) list
2424val to_system_env : t -> string array
2525+val append_to_system_env : string array -> t -> string array
25262627val lookup : Variables.t -> t -> string option
2728val lookup_nonempty : Variables.t -> t -> string option
···4142val add : Variables.t -> string -> t -> t
4243val add_if_undefined : Variables.t -> string -> t -> t
4344val add_bindings : (Variables.t * string) list -> t -> t
4545+4646+val unsetenv : Variables.t -> t -> t
4747+(** [unsetenv env name] causes [name] to be ignored from the underlying system
4848+ environment *)
44494550val append : Variables.t -> string -> t -> t
4651
+2-3
ocamltest/main.ml
···8686 let (msg, children_behavior, summary) = match behavior with
8787 | Skip_all_tests -> "n/a", Skip_all_tests, No_failure
8888 | Run env ->
8989- let testenv0 = interprete_environment_statements env testenvspec in
8989+ let testenv0 = interpret_environment_statements env testenvspec in
9090 let testenv = List.fold_left apply_modifiers testenv0 env_modifiers in
9191 let (result, newenv) = Tests.run log testenv test in
9292 let msg = Result.string_of_result result in
···193193 let rootenv =
194194 Environments.initialize Environments.Pre log initial_environment in
195195 let rootenv =
196196- interprete_environment_statements
197197- rootenv rootenv_statements in
196196+ interpret_environment_statements rootenv rootenv_statements in
198197 let rootenv = Environments.initialize Environments.Post log rootenv in
199198 let common_prefix = " ... testing '" ^ test_basename ^ "' with" in
200199 let initial_status =
+9-8
ocamltest/ocaml_actions.ml
···533533 program
534534 ] in
535535 let systemenv =
536536- Array.append
536536+ Environments.append_to_system_env
537537 default_ocaml_env
538538- (Environments.to_system_env (env_with_lib_unix env))
538538+ (env_with_lib_unix env)
539539 in
540540 let expected_exit_status = 0 in
541541 let exit_status =
···570570 ] in
571571 let ocamllib = [| (Printf.sprintf "OCAMLLIB=%s" tools_directory) |] in
572572 let systemenv =
573573- Array.concat
574574- [
575575- default_ocaml_env;
576576- ocamllib;
577577- (Environments.to_system_env (env_with_lib_unix env))
578578- ]
573573+ Environments.append_to_system_env
574574+ (Array.concat
575575+ [
576576+ default_ocaml_env;
577577+ ocamllib;
578578+ ])
579579+ (env_with_lib_unix env)
579580 in
580581 let expected_exit_status = 0 in
581582 let exit_status =
+2-2
ocamltest/ocaml_variables.ml
···5454 if local_value="" then current_value else
5555 if current_value="" then local_value else
5656 String.concat Filename.path_sep [local_value; current_value] in
5757- Printf.sprintf "%s=%s" caml_ld_library_path_name new_value
5757+ (caml_ld_library_path_name, new_value)
58585959let caml_ld_library_path =
6060 make_with_exporter
···183183 "Expected exit status of ocamlopt.opt")
184184185185let export_ocamlrunparam value =
186186- Printf.sprintf "%s=%s" "OCAMLRUNPARAM" value
186186+ ("OCAMLRUNPARAM", value)
187187188188let ocamlrunparam =
189189 make_with_exporter
···163163164164 /* Compute length of local environment */
165165 localenv_length = 0;
166166- q = localenv;
167167- while (*q != NULL) {
166166+ for (q = localenv; *q != NULL; q++) {
168167 localenv_length += wcslen(*q) + 1;
169169- q++;
170168 }
171169172170 /* Build new env that contains both process and local env */
···178176 }
179177 r = env;
180178 p = process_env;
179179+ /* Copy process_env to env only if the given names are not in localenv */
181180 while (*p != L'\0') {
181181+ wchar_t *pos_eq = wcschr(p, L'=');
182182+ int copy = 1;
182183 l = wcslen(p) + 1; /* also count terminating '\0' */
183183- memcpy(r, p, l * sizeof(WCHAR));
184184+ /* Temporarily change the = to \0 for wcscmp */
185185+ *pos_eq = L'\0';
186186+ for (q = localenv; *q != NULL; q++) {
187187+ wchar_t *pos_eq2 = wcschr(*q, L'=');
188188+ /* Compare this name in localenv with the current one in processenv */
189189+ if (pos_eq2) *pos_eq2 = L'\0';
190190+ if (!wcscmp(*q, p)) copy = 0;
191191+ if (pos_eq2) *pos_eq2 = L'=';
192192+ }
193193+ *pos_eq = L'=';
194194+ if (copy) {
195195+ /* This name is not marked for deletion/update in localenv, so copy */
196196+ memcpy(r, p, l * sizeof(WCHAR));
197197+ r += l;
198198+ }
184199 p += l;
185185- r += l;
186200 }
187201 FreeEnvironmentStrings(process_env);
188188- q = localenv;
189189- while (*q != NULL) {
190190- l = wcslen(*q) + 1;
191191- memcpy(r, *q, l * sizeof(WCHAR));
192192- r += l;
193193- q++;
202202+ for (q = localenv; *q != NULL; q++) {
203203+ /* A string in localenv without '=' signals deletion, which has been done */
204204+ wchar_t *pos_eq = wcschr(*q, L'=');
205205+ if (pos_eq) {
206206+ l = wcslen(*q) + 1;
207207+ memcpy(r, *q, l * sizeof(WCHAR));
208208+ r += l;
209209+ }
194210 }
195211 *r = L'\0';
196212 return env;
+1
ocamltest/tsl_ast.ml
···2424 | Assignment of bool * string located * string located (* variable = value *)
2525 | Append of string located * string located
2626 | Include of string located (* include named environment *)
2727+ | Unset of string located (* clear environment variable *)
27282829type tsl_item =
2930 | Environment_statement of environment_statement located
+1
ocamltest/tsl_ast.mli
···2424 | Assignment of bool * string located * string located (* variable = value *)
2525 | Append of string located * string located (* variable += value *)
2626 | Include of string located (* include named environment *)
2727+ | Unset of string located (* clear environment variable *)
27282829type tsl_item =
2930 | Environment_statement of environment_statement located
+1
ocamltest/tsl_lexer.mll
···4747 match s with
4848 | "include" -> INCLUDE
4949 | "set" -> SET
5050+ | "unset" -> UNSET
5051 | "with" -> WITH
5152 | _ -> IDENTIFIER s
5253 }
+3-1
ocamltest/tsl_parser.mly
···3737%token <int> TEST_DEPTH
3838%token EQUAL PLUSEQUAL
3939/* %token COLON */
4040-%token INCLUDE SET WITH
4040+%token INCLUDE SET UNSET WITH
4141%token <string> IDENTIFIER
4242%token <string> STRING
4343···7676 { mkenvstmt (Append ($1, $3)) }
7777| SET identifier EQUAL string
7878 { mkenvstmt (Assignment (true, $2, $4)) }
7979+| UNSET identifier
8080+ { mkenvstmt (Unset $2) }
79818082| INCLUDE identifier
8183 { mkenvstmt (Include $2) }
+10-3
ocamltest/tsl_semantics.ml
···6767 with Variables.No_such_variable name ->
6868 no_such_variable loc name
69697070-let interprete_environment_statement env statement = match statement.node with
7070+let interpret_environment_statement env statement = match statement.node with
7171 | Assignment (decl, var, value) ->
7272 add_to_env decl statement.loc var.node value.node env
7373 | Append (var, value) ->
7474 append_to_env statement.loc var.node value.node env
7575 | Include modifiers_name ->
7676 apply_modifiers env modifiers_name
7777+ | Unset var ->
7878+ let var =
7979+ match Variables.find_variable var.node with
8080+ | None -> Variables.make (var.node,"User variable")
8181+ | Some var -> var
8282+ in
8383+ Environments.unsetenv var env
77847878-let interprete_environment_statements env l =
7979- List.fold_left interprete_environment_statement env l
8585+let interpret_environment_statements env l =
8686+ List.fold_left interpret_environment_statement env l
80878188type test_tree =
8289 | Node of
···17171818type value = string
19192020-type exporter = value -> string
2020+type exporter = value -> string * string
21212222type t = {
2323 variable_name : string;
···33333434exception No_such_variable of string
35353636-let default_exporter varname value = Printf.sprintf "%s=%s" varname value
3636+let default_exporter varname value = (varname, value)
37373838let make (name, description) =
3939 if name="" then raise Empty_variable_name else {
···6565 with Not_found -> None
66666767let string_of_binding variable value =
6868- variable.variable_exporter value
6868+ let (varname, value) = variable.variable_exporter value in
6969+ Printf.sprintf "%s=%s" varname value
69707071let get_registered_variables () =
7172 let f _variable_name variable variable_list = variable::variable_list in
+1-1
ocamltest/variables.mli
···17171818type value = string
19192020-type exporter = value -> string
2020+type exporter = value -> string * string
21212222type t
2323
+2-1
parsing/ast_mapper.ml
···486486 | Ppat_var s -> var ~loc ~attrs (map_loc sub s)
487487 | Ppat_alias (p, s) -> alias ~loc ~attrs (sub.pat sub p) (map_loc sub s)
488488 | Ppat_constant c -> constant ~loc ~attrs (sub.constant sub c)
489489- | Ppat_interval (c1, c2) -> interval ~loc ~attrs c1 c2
489489+ | Ppat_interval (c1, c2) ->
490490+ interval ~loc ~attrs (sub.constant sub c1) (sub.constant sub c2)
490491 | Ppat_tuple pl -> tuple ~loc ~attrs (List.map (sub.pat sub) pl)
491492 | Ppat_construct (l, p) ->
492493 construct ~loc ~attrs (map_loc sub l)
···4444 with (4 x/95) (seq (ignore x/95) 1)))
4545- : bool = false
4646|}];;
4747+4848+(* Regression test for #3780 *)
4949+let _ = fun a b ->
5050+ match a, b with
5151+ | ((true, _) as _g)
5252+ | ((false, _) as _g) -> ()
5353+[%%expect{|
5454+(function a/102[int] b/103 : int 0)
5555+- : bool -> 'a -> unit = <fun>
5656+|}];;
5757+5858+(* More complete tests.
5959+6060+ The test cases below compare the compiler output on alias patterns
6161+ that are outside an or-pattern (handled during half-simplification,
6262+ then flattened) or inside an or-pattern (handled during simplification).
6363+6464+ We used to have a Cannot_flatten exception that would result in fairly
6565+ different code generated in both cases, but now the compilation strategy
6666+ is fairly similar.
6767+*)
6868+let _ = fun a b -> match a, b with
6969+| (true, _) as p -> p
7070+| (false, _) as p -> p
7171+(* outside, trivial *)
7272+[%%expect {|
7373+(function a/106[int] b/107 (let (p/108 =a (makeblock 0 a/106 b/107)) p/108))
7474+- : bool -> 'a -> bool * 'a = <fun>
7575+|}]
7676+7777+let _ = fun a b -> match a, b with
7878+| ((true, _) as p)
7979+| ((false, _) as p) -> p
8080+(* inside, trivial *)
8181+[%%expect{|
8282+(function a/110[int] b/111 (let (p/112 =a (makeblock 0 a/110 b/111)) p/112))
8383+- : bool -> 'a -> bool * 'a = <fun>
8484+|}];;
8585+8686+let _ = fun a b -> match a, b with
8787+| (true as x, _) as p -> x, p
8888+| (false as x, _) as p -> x, p
8989+(* outside, simple *)
9090+[%%expect {|
9191+(function a/116[int] b/117
9292+ (let (x/118 =a[int] a/116 p/119 =a (makeblock 0 a/116 b/117))
9393+ (makeblock 0 (int,*) x/118 p/119)))
9494+- : bool -> 'a -> bool * (bool * 'a) = <fun>
9595+|}]
9696+9797+let _ = fun a b -> match a, b with
9898+| ((true as x, _) as p)
9999+| ((false as x, _) as p) -> x, p
100100+(* inside, simple *)
101101+[%%expect {|
102102+(function a/122[int] b/123
103103+ (let (x/124 =a[int] a/122 p/125 =a (makeblock 0 a/122 b/123))
104104+ (makeblock 0 (int,*) x/124 p/125)))
105105+- : bool -> 'a -> bool * (bool * 'a) = <fun>
106106+|}]
107107+108108+let _ = fun a b -> match a, b with
109109+| (true as x, _) as p -> x, p
110110+| (false, x) as p -> x, p
111111+(* outside, complex *)
112112+[%%expect{|
113113+(function a/132[int] b/133[int]
114114+ (if a/132
115115+ (let (x/134 =a[int] a/132 p/135 =a (makeblock 0 a/132 b/133))
116116+ (makeblock 0 (int,*) x/134 p/135))
117117+ (let (x/136 =a b/133 p/137 =a (makeblock 0 a/132 b/133))
118118+ (makeblock 0 (int,*) x/136 p/137))))
119119+- : bool -> bool -> bool * (bool * bool) = <fun>
120120+|}]
121121+122122+let _ = fun a b -> match a, b with
123123+| ((true as x, _) as p)
124124+| ((false, x) as p)
125125+ -> x, p
126126+(* inside, complex *)
127127+[%%expect{|
128128+(function a/138[int] b/139[int]
129129+ (catch
130130+ (if a/138
131131+ (let (x/146 =a[int] a/138 p/147 =a (makeblock 0 a/138 b/139))
132132+ (exit 10 x/146 p/147))
133133+ (let (x/144 =a b/139 p/145 =a (makeblock 0 a/138 b/139))
134134+ (exit 10 x/144 p/145)))
135135+ with (10 x/140[int] p/141) (makeblock 0 (int,*) x/140 p/141)))
136136+- : bool -> bool -> bool * (bool * bool) = <fun>
137137+|}]
138138+139139+(* here flattening is an optimisation: the allocation is moved as an
140140+ alias within each branch, and in the first branch it is unused and
141141+ will be removed by simplification, so the final code
142142+ (see the -dlambda output) will not allocate in the first branch. *)
143143+let _ = fun a b -> match a, b with
144144+| (true as x, _) as _p -> x, (true, true)
145145+| (false as x, _) as p -> x, p
146146+(* outside, onecase *)
147147+[%%expect {|
148148+(function a/148[int] b/149[int]
149149+ (if a/148
150150+ (let (x/150 =a[int] a/148 _p/151 =a (makeblock 0 a/148 b/149))
151151+ (makeblock 0 (int,*) x/150 [0: 1 1]))
152152+ (let (x/152 =a[int] a/148 p/153 =a (makeblock 0 a/148 b/149))
153153+ (makeblock 0 (int,*) x/152 p/153))))
154154+- : bool -> bool -> bool * (bool * bool) = <fun>
155155+|}]
156156+157157+let _ = fun a b -> match a, b with
158158+| ((true as x, _) as p)
159159+| ((false as x, _) as p) -> x, p
160160+(* inside, onecase *)
161161+[%%expect{|
162162+(function a/154[int] b/155
163163+ (let (x/156 =a[int] a/154 p/157 =a (makeblock 0 a/154 b/155))
164164+ (makeblock 0 (int,*) x/156 p/157)))
165165+- : bool -> 'a -> bool * (bool * 'a) = <fun>
166166+|}]
167167+168168+type 'a tuplist = Nil | Cons of ('a * 'a tuplist)
169169+[%%expect{|
170170+0
171171+type 'a tuplist = Nil | Cons of ('a * 'a tuplist)
172172+|}]
173173+174174+(* another example where we avoid an allocation in the first case *)
175175+let _ =fun a b -> match a, b with
176176+| (true, Cons p) -> p
177177+| (_, _) as p -> p
178178+(* outside, tuplist *)
179179+[%%expect {|
180180+(function a/167[int] b/168
181181+ (catch
182182+ (if a/167 (if b/168 (let (p/169 =a (field_imm 0 b/168)) p/169) (exit 12))
183183+ (exit 12))
184184+ with (12) (let (p/170 =a (makeblock 0 a/167 b/168)) p/170)))
185185+- : bool -> bool tuplist -> bool * bool tuplist = <fun>
186186+|}]
187187+188188+let _ = fun a b -> match a, b with
189189+| (true, Cons p)
190190+| ((_, _) as p) -> p
191191+(* inside, tuplist *)
192192+[%%expect{|
193193+(function a/171[int] b/172
194194+ (catch
195195+ (catch
196196+ (if a/171
197197+ (if b/172 (let (p/176 =a (field_imm 0 b/172)) (exit 13 p/176))
198198+ (exit 14))
199199+ (exit 14))
200200+ with (14) (let (p/175 =a (makeblock 0 a/171 b/172)) (exit 13 p/175)))
201201+ with (13 p/173) p/173))
202202+- : bool -> bool tuplist -> bool * bool tuplist = <fun>
203203+|}]
+3-1
testsuite/tests/lib-threads/pr7638.ml
···11(* TEST
2233+unset DOES_NOT_EXIST
44+35* hassysthreads
46include systhreads
57** bytecode
···1517 | s -> print_string "Surprising but OK\n"
16181719let _ =
1818- let th = Thread.create crashme "no such variable" in
2020+ let th = Thread.create crashme "DOES_NOT_EXIST" in
1921 Thread.join th
···22 (let
33 (gen_cmp = (function x y : int (caml_compare x y))
44 int_cmp = (function x[int] y[int] : int (compare_ints x y))
55- bool_cmp = (function x y : int (compare_ints x y))
66- intlike_cmp = (function x y : int (compare_ints x y))
55+ bool_cmp = (function x[int] y[int] : int (compare_ints x y))
66+ intlike_cmp = (function x[int] y[int] : int (compare_ints x y))
77 float_cmp = (function x[float] y[float] : int (compare_floats x y))
88 string_cmp = (function x y : int (caml_string_compare x y))
99 int32_cmp = (function x[int32] y[int32] : int (compare_bints int32 x y))
···1111 nativeint_cmp =
1212 (function x[nativeint] y[nativeint] : int
1313 (compare_bints nativeint x y))
1414- gen_eq = (function x y (caml_equal x y))
1515- int_eq = (function x[int] y[int] (== x y))
1616- bool_eq = (function x y (== x y))
1717- intlike_eq = (function x y (== x y))
1818- float_eq = (function x[float] y[float] (==. x y))
1919- string_eq = (function x y (caml_string_equal x y))
2020- int32_eq = (function x[int32] y[int32] (Int32.== x y))
2121- int64_eq = (function x[int64] y[int64] (Int64.== x y))
2222- nativeint_eq = (function x[nativeint] y[nativeint] (Nativeint.== x y))
2323- gen_ne = (function x y (caml_notequal x y))
2424- int_ne = (function x[int] y[int] (!= x y))
2525- bool_ne = (function x y (!= x y))
2626- intlike_ne = (function x y (!= x y))
2727- float_ne = (function x[float] y[float] (!=. x y))
2828- string_ne = (function x y (caml_string_notequal x y))
2929- int32_ne = (function x[int32] y[int32] (Int32.!= x y))
3030- int64_ne = (function x[int64] y[int64] (Int64.!= x y))
3131- nativeint_ne = (function x[nativeint] y[nativeint] (Nativeint.!= x y))
3232- gen_lt = (function x y (caml_lessthan x y))
3333- int_lt = (function x[int] y[int] (< x y))
3434- bool_lt = (function x y (< x y))
3535- intlike_lt = (function x y (< x y))
3636- float_lt = (function x[float] y[float] (<. x y))
3737- string_lt = (function x y (caml_string_lessthan x y))
3838- int32_lt = (function x[int32] y[int32] (Int32.< x y))
3939- int64_lt = (function x[int64] y[int64] (Int64.< x y))
4040- nativeint_lt = (function x[nativeint] y[nativeint] (Nativeint.< x y))
4141- gen_gt = (function x y (caml_greaterthan x y))
4242- int_gt = (function x[int] y[int] (> x y))
4343- bool_gt = (function x y (> x y))
4444- intlike_gt = (function x y (> x y))
4545- float_gt = (function x[float] y[float] (>. x y))
4646- string_gt = (function x y (caml_string_greaterthan x y))
4747- int32_gt = (function x[int32] y[int32] (Int32.> x y))
4848- int64_gt = (function x[int64] y[int64] (Int64.> x y))
4949- nativeint_gt = (function x[nativeint] y[nativeint] (Nativeint.> x y))
5050- gen_le = (function x y (caml_lessequal x y))
5151- int_le = (function x[int] y[int] (<= x y))
5252- bool_le = (function x y (<= x y))
5353- intlike_le = (function x y (<= x y))
5454- float_le = (function x[float] y[float] (<=. x y))
5555- string_le = (function x y (caml_string_lessequal x y))
5656- int32_le = (function x[int32] y[int32] (Int32.<= x y))
5757- int64_le = (function x[int64] y[int64] (Int64.<= x y))
5858- nativeint_le = (function x[nativeint] y[nativeint] (Nativeint.<= x y))
5959- gen_ge = (function x y (caml_greaterequal x y))
6060- int_ge = (function x[int] y[int] (>= x y))
6161- bool_ge = (function x y (>= x y))
6262- intlike_ge = (function x y (>= x y))
6363- float_ge = (function x[float] y[float] (>=. x y))
6464- string_ge = (function x y (caml_string_greaterequal x y))
6565- int32_ge = (function x[int32] y[int32] (Int32.>= x y))
6666- int64_ge = (function x[int64] y[int64] (Int64.>= x y))
6767- nativeint_ge = (function x[nativeint] y[nativeint] (Nativeint.>= x y))
1414+ gen_eq = (function x y : int (caml_equal x y))
1515+ int_eq = (function x[int] y[int] : int (== x y))
1616+ bool_eq = (function x[int] y[int] : int (== x y))
1717+ intlike_eq = (function x[int] y[int] : int (== x y))
1818+ float_eq = (function x[float] y[float] : int (==. x y))
1919+ string_eq = (function x y : int (caml_string_equal x y))
2020+ int32_eq = (function x[int32] y[int32] : int (Int32.== x y))
2121+ int64_eq = (function x[int64] y[int64] : int (Int64.== x y))
2222+ nativeint_eq =
2323+ (function x[nativeint] y[nativeint] : int (Nativeint.== x y))
2424+ gen_ne = (function x y : int (caml_notequal x y))
2525+ int_ne = (function x[int] y[int] : int (!= x y))
2626+ bool_ne = (function x[int] y[int] : int (!= x y))
2727+ intlike_ne = (function x[int] y[int] : int (!= x y))
2828+ float_ne = (function x[float] y[float] : int (!=. x y))
2929+ string_ne = (function x y : int (caml_string_notequal x y))
3030+ int32_ne = (function x[int32] y[int32] : int (Int32.!= x y))
3131+ int64_ne = (function x[int64] y[int64] : int (Int64.!= x y))
3232+ nativeint_ne =
3333+ (function x[nativeint] y[nativeint] : int (Nativeint.!= x y))
3434+ gen_lt = (function x y : int (caml_lessthan x y))
3535+ int_lt = (function x[int] y[int] : int (< x y))
3636+ bool_lt = (function x[int] y[int] : int (< x y))
3737+ intlike_lt = (function x[int] y[int] : int (< x y))
3838+ float_lt = (function x[float] y[float] : int (<. x y))
3939+ string_lt = (function x y : int (caml_string_lessthan x y))
4040+ int32_lt = (function x[int32] y[int32] : int (Int32.< x y))
4141+ int64_lt = (function x[int64] y[int64] : int (Int64.< x y))
4242+ nativeint_lt =
4343+ (function x[nativeint] y[nativeint] : int (Nativeint.< x y))
4444+ gen_gt = (function x y : int (caml_greaterthan x y))
4545+ int_gt = (function x[int] y[int] : int (> x y))
4646+ bool_gt = (function x[int] y[int] : int (> x y))
4747+ intlike_gt = (function x[int] y[int] : int (> x y))
4848+ float_gt = (function x[float] y[float] : int (>. x y))
4949+ string_gt = (function x y : int (caml_string_greaterthan x y))
5050+ int32_gt = (function x[int32] y[int32] : int (Int32.> x y))
5151+ int64_gt = (function x[int64] y[int64] : int (Int64.> x y))
5252+ nativeint_gt =
5353+ (function x[nativeint] y[nativeint] : int (Nativeint.> x y))
5454+ gen_le = (function x y : int (caml_lessequal x y))
5555+ int_le = (function x[int] y[int] : int (<= x y))
5656+ bool_le = (function x[int] y[int] : int (<= x y))
5757+ intlike_le = (function x[int] y[int] : int (<= x y))
5858+ float_le = (function x[float] y[float] : int (<=. x y))
5959+ string_le = (function x y : int (caml_string_lessequal x y))
6060+ int32_le = (function x[int32] y[int32] : int (Int32.<= x y))
6161+ int64_le = (function x[int64] y[int64] : int (Int64.<= x y))
6262+ nativeint_le =
6363+ (function x[nativeint] y[nativeint] : int (Nativeint.<= x y))
6464+ gen_ge = (function x y : int (caml_greaterequal x y))
6565+ int_ge = (function x[int] y[int] : int (>= x y))
6666+ bool_ge = (function x[int] y[int] : int (>= x y))
6767+ intlike_ge = (function x[int] y[int] : int (>= x y))
6868+ float_ge = (function x[float] y[float] : int (>=. x y))
6969+ string_ge = (function x y : int (caml_string_greaterequal x y))
7070+ int32_ge = (function x[int32] y[int32] : int (Int32.>= x y))
7171+ int64_ge = (function x[int64] y[int64] : int (Int64.>= x y))
7272+ nativeint_ge =
7373+ (function x[nativeint] y[nativeint] : int (Nativeint.>= x y))
6874 eta_gen_cmp = (function prim prim stub (caml_compare prim prim))
6975 eta_int_cmp = (function prim prim stub (compare_ints prim prim))
7076 eta_bool_cmp = (function prim prim stub (compare_ints prim prim))
···1414val sys_readdir : string -> string list = <fun>
1515val test_readdir : (string -> string list) -> string list = <fun>
1616val test_open_in : unit -> string list = <fun>
1717-val test_getenv : unit -> (string * string) list = <fun>
1717+val test_getenv : unit -> ((string * string) * (string * string)) list =
1818+ <fun>
1819val test_mkdir : unit -> (bool * bool) list = <fun>
1920val test_chdir : (string -> unit) -> (unit -> 'a) -> 'a list = <fun>
2021val test_rmdir : unit -> bool list = <fun>
···7677val t_sys_chdir : string list = ["été"; "simple"; "sœur"; "你好"]
7778val t_unix_chdir : string list = ["été"; "simple"; "sœur"; "你好"]
7879- : bool list = [false; false; false; false]
7979-val t_getenv : (string * string) list =
8080- [("верблюды", "верблюды"); ("骆驼", "骆驼");
8181- ("קעמל", "קעמל"); ("اونٹ", "اونٹ")]
8080+val t_getenv : ((string * string) * (string * string)) list =
8181+ [(("верблюды", "верблюды"),
8282+ ("верблюдыверблюды", "верблюдыверблюды"));
8383+ (("骆驼", "骆驼"), ("骆驼骆驼", "骆驼骆驼"));
8484+ (("קעמל", "קעמל"), ("קעמלקעמל", "קעמלקעמל"));
8585+ (("اونٹ", "اونٹ"), ("اونٹاونٹ", "اونٹاونٹ"))]
8286- : bool = true
8387
+10-1
testsuite/tests/win-unicode/mltest.ml
···144144;;
145145146146let test_getenv () =
147147+ let equiv l r =
148148+ assert (l = r);
149149+ l, r
150150+ in
147151 let doit key s =
148152 Unix.putenv key s;
149149- Sys.getenv key, getenvironmentenv key
153153+ let l = equiv (Sys.getenv key) (getenvironmentenv key) in
154154+ let r =
155155+ Unix.putenv key (s ^ s);
156156+ equiv (Sys.getenv key) (getenvironmentenv key)
157157+ in
158158+ l, r
150159 in
151160 List.map2 doit foreign_names foreign_names2
152161;;
+4-2
tools/ci/inria/bootstrap/script
···6464 new="$1"
6565 echo Changing executable magic number from ${old} to ${new}
6666 # Change magic number in runtime/caml/exec.h
6767- sed -i 's/\x23define \+EXEC_MAGIC \+\x22'${old}\
6767+ sed -i.tmp 's/\x23define \+EXEC_MAGIC \+\x22'${old}\
6868'\x22/#define EXEC_MAGIC "'${new}'"/' runtime/caml/exec.h
6969+ rm -f runtime/caml/exec.h.tmp
6970 # Change magic number in utils/config.mlp
7070- sed -i 's/let \+exec_magic_number \+= \+\x22'${old}\
7171+ sed -i.tmp 's/let \+exec_magic_number \+= \+\x22'${old}\
7172'\x22/let exec_magic_number = "'${new}'"/' utils/config.mlp
7373+ rm -f utils/config.mlp.tmp
7274}
73757476remove_primitive()
-10
typing/ctype.ml
···53905390let () =
53915391 Env.same_constr := same_constr
5392539253935393-let is_immediate = function
53945394- | Type_immediacy.Unknown -> false
53955395- | Type_immediacy.Always -> true
53965396- | Type_immediacy.Always_on_64bits ->
53975397- (* In bytecode, we don't know at compile time whether we are
53985398- targeting 32 or 64 bits. *)
53995399- !Clflags.native_code && Sys.word_size = 64
54005400-54015393let immediacy env typ =
54025394 match get_desc typ with
54035395 | Tconstr(p, _args, _abbrev) ->
···54245416 else
54255417 Type_immediacy.Always
54265418 | _ -> Type_immediacy.Unknown
54275427-54285428-let maybe_pointer_type env typ = not (is_immediate (immediacy env typ))
-3
typing/ctype.mli
···415415416416val immediacy : Env.t -> type_expr -> Type_immediacy.t
417417418418-val maybe_pointer_type : Env.t -> type_expr -> bool
419419- (* True if type is possibly pointer, false if definitely not a pointer *)
420420-421418(* Stubs *)
422419val package_subtype :
423420 (Env.t -> Path.t -> (Longident.t * type_expr) list ->
+2-2
typing/includecore.ml
···759759 | Some _, None | None, Some _ ->
760760 Some (Incompatible_types_for s)
761761 end
762762- | Rpresent to1, Reither(const2, tl2, _, _) -> begin
763763- match to1, const2, tl2 with
762762+ | Rpresent to1, Reither(const2, ts2, _, _) -> begin
763763+ match to1, const2, ts2 with
764764 | Some t1, false, [t2] -> loop (t1 :: tl1) (t2 :: tl2) pairs
765765 | None, true, [] -> loop tl1 tl2 pairs
766766 | _, _, _ -> Some (Incompatible_types_for s)
+1-6
typing/typedecl.ml
···134134 with Ctype.Unify err ->
135135 raise (Error(loc, Type_clash (env, err)))
136136137137-let get_unboxed_type_representation env ty =
138138- match Typedecl_unboxed.get_unboxed_type_representation env ty with
139139- | Typedecl_unboxed.This x -> Some x
140140- | _ -> None
141141-142137(* Determine if a type's values are represented by floats at run-time. *)
143138let is_float env ty =
144144- match get_unboxed_type_representation env ty with
139139+ match Typedecl_unboxed.get_unboxed_type_representation env ty with
145140 Some ty' ->
146141 begin match get_desc ty' with
147142 Tconstr(p, _, _) -> Path.same p Predef.path_float
···2626 Variant_unboxed)
2727 | Type_record ([{ld_type = arg; _}], Record_unboxed _)), _ ->
2828 begin match Typedecl_unboxed.get_unboxed_type_representation env arg with
2929- | Typedecl_unboxed.Unavailable -> Type_immediacy.Unknown
3030- | Typedecl_unboxed.This argrepr -> Ctype.immediacy env argrepr
3131- | Typedecl_unboxed.Only_on_64_bits argrepr ->
3232- match Ctype.immediacy env argrepr with
3333- | Type_immediacy.Always -> Type_immediacy.Always_on_64bits
3434- | Type_immediacy.Always_on_64bits | Type_immediacy.Unknown as x -> x
2929+ | None -> Type_immediacy.Unknown
3030+ | Some argrepr -> Ctype.immediacy env argrepr
3531 end
3632 | (Type_variant (_ :: _ as cstrs, _), _) ->
3733 if not (List.exists (fun c -> c.Types.cd_args <> Types.Cstr_tuple []) cstrs)
+4-13
typing/typedecl_unboxed.ml
···16161717open Types
18181919-type t =
2020- | Unavailable
2121- | This of type_expr
2222- | Only_on_64_bits of type_expr
2323-2419(* We use the Ctype.expand_head_opt version of expand_head to get access
2520 to the manifest type of private abbreviations. *)
2621let rec get_unboxed_type_representation env ty fuel =
2727- if fuel < 0 then Unavailable else
2222+ if fuel < 0 then None else
2823 let ty = Ctype.expand_head_opt env ty in
2924 match get_desc ty with
3025 | Tconstr (p, args, _) ->
3126 begin match Env.find_type p env with
3232- | exception Not_found -> This ty
3333- | {type_immediate = Always; _} ->
3434- This Predef.type_int
3535- | {type_immediate = Always_on_64bits; _} ->
3636- Only_on_64_bits Predef.type_int
2727+ | exception Not_found -> Some ty
3728 | {type_params; type_kind =
3829 Type_record ([{ld_type = ty2; _}], Record_unboxed _)
3930 | Type_variant ([{cd_args = Cstr_tuple [ty2]; _}], Variant_unboxed)
···4334 let ty2 = match get_desc ty2 with Tpoly (t, _) -> t | _ -> ty2 in
4435 get_unboxed_type_representation env
4536 (Ctype.apply env type_params ty2 args) (fuel - 1)
4646- | _ -> This ty
3737+ | _ -> Some ty
4738 end
4848- | _ -> This ty
3939+ | _ -> Some ty
49405041let get_unboxed_type_representation env ty =
5142 (* Do not give too much fuel: PR#7424 *)
+1-6
typing/typedecl_unboxed.mli
···16161717open Types
18181919-type t =
2020- | Unavailable
2121- | This of type_expr
2222- | Only_on_64_bits of type_expr
2323-2419(* for typeopt.ml *)
2525-val get_unboxed_type_representation: Env.t -> type_expr -> t
2020+val get_unboxed_type_representation: Env.t -> type_expr -> type_expr option
+29-23
typing/typeopt.ml
···2727 | Tconstr (p, _, _) ->
2828 begin match Env.find_type p env with
2929 | {type_kind = ( Type_variant (_, Variant_unboxed)
3030- | Type_record (_, Record_unboxed _) ); _} ->
3131- begin match Typedecl.get_unboxed_type_representation env ty with
3232- | None -> ty
3333- | Some ty2 -> ty2
3030+ | Type_record (_, Record_unboxed _) ); _} -> begin
3131+ match Typedecl_unboxed.get_unboxed_type_representation env ty with
3232+ | None -> ty
3333+ | Some ty2 -> ty2
3434 end
3535 | _ -> ty
3636 | exception Not_found -> ty
···5656 | Tconstr(p, _, _) -> Path.same p base_ty_path
5757 | _ -> false
58585959+let is_immediate = function
6060+ | Type_immediacy.Unknown -> false
6161+ | Type_immediacy.Always -> true
6262+ | Type_immediacy.Always_on_64bits ->
6363+ (* In bytecode, we don't know at compile time whether we are
6464+ targeting 32 or 64 bits. *)
6565+ !Clflags.native_code && Sys.word_size = 64
6666+5967let maybe_pointer_type env ty =
6068 let ty = scrape_ty env ty in
6161- if Ctype.maybe_pointer_type env ty then
6262- Pointer
6363- else
6464- Immediate
6969+ if is_immediate (Ctype.immediacy env ty) then Immediate
7070+ else Pointer
65716672let maybe_pointer exp = maybe_pointer_type exp.exp_env exp.exp_type
6773···160166 (Pbigarray_unknown, Pbigarray_unknown_layout)
161167162168let value_kind env ty =
163163- match scrape env ty with
164164- | Tconstr(p, _, _) when Path.same p Predef.path_int ->
165165- Pintval
166166- | Tconstr(p, _, _) when Path.same p Predef.path_char ->
167167- Pintval
168168- | Tconstr(p, _, _) when Path.same p Predef.path_float ->
169169- Pfloatval
170170- | Tconstr(p, _, _) when Path.same p Predef.path_int32 ->
171171- Pboxedintval Pint32
172172- | Tconstr(p, _, _) when Path.same p Predef.path_int64 ->
173173- Pboxedintval Pint64
174174- | Tconstr(p, _, _) when Path.same p Predef.path_nativeint ->
175175- Pboxedintval Pnativeint
176176- | _ ->
177177- Pgenval
169169+ let ty = scrape_ty env ty in
170170+ if is_immediate (Ctype.immediacy env ty) then Pintval
171171+ else begin
172172+ match get_desc ty with
173173+ | Tconstr(p, _, _) when Path.same p Predef.path_float ->
174174+ Pfloatval
175175+ | Tconstr(p, _, _) when Path.same p Predef.path_int32 ->
176176+ Pboxedintval Pint32
177177+ | Tconstr(p, _, _) when Path.same p Predef.path_int64 ->
178178+ Pboxedintval Pint64
179179+ | Tconstr(p, _, _) when Path.same p Predef.path_nativeint ->
180180+ Pboxedintval Pnativeint
181181+ | _ ->
182182+ Pgenval
183183+ end
178184179185let function_return_value_kind env ty =
180186 match is_function_type env ty with