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

Possible bug in ocamlopt 3.0 on x86 #2509

Closed
vicuna opened this issue Jun 27, 2000 · 3 comments
Closed

Possible bug in ocamlopt 3.0 on x86 #2509

vicuna opened this issue Jun 27, 2000 · 3 comments

Comments

@vicuna
Copy link

vicuna commented Jun 27, 2000

Original bug ID: 149
Reporter: administrator
Status: closed (set by @xavierleroy on 2006-06-17T09:20:15Z)
Resolution: fixed
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)

Bug description

I might have found an bug in ocamlopt that I like to report. The
system where the bug can be observed is a i386 Linux 2.2.16 using
OCaml 3.0. The bug appears in an OCaml lex scanner in the following
situation:

let get = Lexing.lexeme

let digit = ['0'-'9']
let nat = digit+

and line = parse
eof { fun map l ->
error lexbuf map "unterminated line directive"
}
| ws+ { fun map l -> line lexbuf map l }
...
| nat { fun map l ->

                      (* inline the l' expression caused an
                      int_of_string failure with ocamlopt 
                      XXX *)
                      
                      let l' = int_of_string (get lexbuf)
                      in  line lexbuf map (int_of_string (get lexbuf))
                    }                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

...

The marked int_of_string function raises a Failure exception. This
does not happen when instead the let-bond value l' is used or the code
is translated to bytecode. I suspect that order of evaluation might
be a problem. Obviuosly int_of_string should only receive numbers
that it can convert because the scanner just matches these.

The scanner function line is used to scan cpp-like line directives:

    # 23 "file"

I have not broken down the problem to a very small program as you
might wish. But to lessen your pain I have created a tar file with
just the sources of the system and a very simple shell script to build
the system to observe the error. So although the system is quite large
it should be easy to build.

You can find it at:

    http://www.eecs.harvard.edu/~lindig/download/ocaml-bug.tar.gz

The tar archive contains a sh-script 'build' that builds the system (a
compiler) and runs it on a test file that should reproduce the bug.
The lexer code mentioned above is in line 345 in the file
src/scan.mll. The binary to run is:

    src/qc--.opt -lex bug.c--

The qc--.opt binary reports the tokens it scans to stdout. When it
reaches the first line directive in bug.c-- in the third line the
error should show:

./src/qc--.opt -lex bug.c--
bug.c-- 1 1 IMPORT
bug.c-- 1 8 BITSn(32)
bug.c-- 1 15 ID(printf)
bug.c-- 1 21 COMMA
bug.c-- 1 23 ID(sqrt)
bug.c-- 1 27 SEMI
bug.c-- 2 1 EXPORT
bug.c-- 2 8 ID(foo)
bug.c-- 2 11 COMMA
bug.c-- 2 13 ID(bar)
bug.c-- 2 16 SEMI
Uncaught exception: Failure("int_of_string")

It would be helpful when the Failure exception includes the offending
argument in case of xxx_of_string functions.

-- Christian

--
Christian Lindig Harvard University - EECS
lindig@eecs.harvard.edu 33 Oxford St, MD 242, Cambridge MA 02138
phone: (617) 496-7157 http://www.eecs.harvard.edu/~lindig/

@vicuna
Copy link
Author

vicuna commented Jun 27, 2000

Comment author: administrator

I might have found an bug in ocamlopt that I like to report. The
system where the bug can be observed is a i386 Linux 2.2.16 using
OCaml 3.0.

It's a problem with the evaluation order of function arguments. Namely:

and line = parse
| nat { fun map l ->

                      (* inline the l' expression caused an
                      int_of_string failure with ocamlopt 
                      XXX *)
                      
                      let l' = int_of_string (get lexbuf)
                      in  line lexbuf map (int_of_string (get lexbuf))
                    }                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Ocamlopt "sees" that line is a 1-argument function, so it compiles the
last line as
(line lexbuf) map (int_of_string (get lexbuf))

Then, it chooses to evaluate "line lexbuf" first, which of course
changes the location of the current token in lexbuf, then "map" and
"int_of_string (get lexbuf)", and the "get lexbuf" returns the current
token, not the one that was matched by the "nat" regular expression.

What's more confusing is that ocamlc should get the expected behavior
on this code, because it sticks to a strict right-to-left evaluation
order.

The ocamlopt semantics is basically correct w.r.t. the language spec,
which says that evaluation order for function arguments is
unspecified. However, I agree that the difference in semantics
between ocamlc and ocamlopt is unpleasant, and it would be better if
ocamlopt sticks to right-to-left evaluation all the time.

Bottom line: better let-bind this call to "get lexbuf"!

Best regards,

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Jun 27, 2000

Comment author: administrator

It would be nice if ocamlopt implemented exactly the same evaluation order as
ocamlc

@vicuna
Copy link
Author

vicuna commented Jun 17, 2006

Comment author: @xavierleroy

Discrepancy in evaluation order between ocamlc and ocamlopt fixed (I believe) in 3.09.0.

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

1 participant