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

Compiler bug when matching on floats #5758

Closed
vicuna opened this issue Sep 10, 2012 · 7 comments
Closed

Compiler bug when matching on floats #5758

vicuna opened this issue Sep 10, 2012 · 7 comments
Assignees
Labels
Milestone

Comments

@vicuna
Copy link

vicuna commented Sep 10, 2012

Original bug ID: 5758
Reporter: dwu
Assigned to: @maranget
Status: closed (set by @maranget on 2012-09-27T12:31:18Z)
Resolution: fixed
Priority: normal
Severity: major
Version: 3.12.1
Target version: 4.00.1+dev
Fixed in version: 4.00.1+dev
Category: ~DO NOT USE (was: OCaml general)
Monitored by: @hcarty yminsky pzimmer @alainfrisch

Bug description

The following code outputs "Failed match A then later matched", when it should instead output "Matched A".

let test x str =
match (x, str) with
| (1. , "A") -> print_endline "Matched A";
| (1.0, "B") -> print_endline "Matched B";
| (1. , "C") -> print_endline "Matched C";
| result ->
match result with
| (1., "A") -> print_endline "Failed match A then later matched"
| _ -> print_endline "Failed twice"
;;
test 1. "A";;

However, if the line
| (1.0, "B") -> print_endline "Matched B";
is changed to
| (1. , "B") -> print_endline "Matched B";
then the code correctly outputs "Matched A".

Steps to reproduce

Run in a toplevel.

@vicuna
Copy link
Author

vicuna commented Sep 10, 2012

Comment author: @garrigue

Try using ocaml -dlambda.
It looks like a problem in pattern-matching compilation.
For some mysterious reason, we get two branches, for 1. and 1.0

@vicuna
Copy link
Author

vicuna commented Sep 10, 2012

Comment author: @garrigue

Actually, it is pretty bad: floats are compared as strings during pattern-matching compilation, so that you can create an arbitrary number of branches...
Why do we have Const_float of string rather than Const_float of float in asttypes.mli ?

@vicuna
Copy link
Author

vicuna commented Sep 10, 2012

Comment author: pzimmer

Here is a simpler example (you need to turn off errors on warnings):

match 0. with 0. -> 0 | 0.0 -> 1 | 0. -> 2;;

This returns 1, i.e. the compiler does not respect the ordering of the branches.

Another sign of what is going on is this:

match 0. with 0. -> 0 | 0.0 -> 1 | _ -> 2;;

This does not raise a warning about unused match case (while replacing 0.0 with 0. does).

I am sure similar examples would work with other styles of redundant float representations (i.e. 0.01 vs 1e-2).

@vicuna
Copy link
Author

vicuna commented Sep 11, 2012

Comment author: @alainfrisch

Why do we have Const_float of string rather than Const_float of float in asttypes.mli ?

I'm not sure. I guess the rationale is to avoid generating different .cmo for the same source when the libc version of float_of_string behaves in a non-standard way. The interpretation of floats is delegated to runtime (for bytecode) and to the assembler (native). But this does not really work, because some parts in the pattern matching compiler already use float_of_string at compile time to check equality of floats represented as strings (but not everywhere).

@vicuna
Copy link
Author

vicuna commented Sep 19, 2012

Comment author: @garrigue

Fix committed in trunk revision 12937.

@vicuna
Copy link
Author

vicuna commented Sep 27, 2012

Comment author: @maranget

Checked fix, looks ok.
--Luc

@vicuna vicuna closed this as completed Sep 27, 2012
@vicuna
Copy link
Author

vicuna commented Sep 27, 2012

Comment author: @garrigue

Committed in 4.00 too, since this was the point of this quick fix.
At revision 12961.

@vicuna vicuna added this to the 4.00.1 milestone Mar 14, 2019
@vicuna vicuna added the bug label Mar 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants