Euphoria
Ticket #655:
using integer for return value atom fails translated
-
Reported by
ne1uno
Apr 20, 2011
type checking was active and the actual program works interpreted. seems like it should be a forgivable user error, or something that an advanced lint test could catch, but the translator should be able to flag it as an error or better, just do the right thing.
actual program was more like
atom tot_time = 0
...
if x then
--integer tol = datetime:diff(online, offline) --fails translated
atom tol = datetime:diff(online, offline)
tot_time += tol/60/60
end if
I will try again to isolate the problem if required. maybe online - offline was winding up negative in a translated integer? possible at some point the difference between the dates was larger than integer and wrapped around? seems to happen on the first compare, which would have been minutes or a few hours difference at the most.
found a simpler test case:
include std/unittest.e
atom result = 0
function return_atom()
return 1.0
end function
test_equal("return_atom()/2 = .5", 0.5, return_atom()/2)
-- this is a typecheck error
-- integer retval_int = return_atom()/2
integer retval_int = return_atom()
result = retval_int/2
test_equal("result = return_atom()/2 = .5", 0.5, result)
-- failed: result = return_atom()/2 = .5, expected: 0.5 but got: -805219256.5
preview button in forum and tickets seems to be broken?
Details
1. Comment by ne1uno
Apr 20, 2011
should mention, "fails translated" was an unfortunate simplification. really what happens is much worse, you get wrong results translated.
2. Comment by mattlewis
Apr 21, 2011
The interpreter appears to be returning an integer from return_atom(), where the translator returns a double. I'm not totally sure about this, but that's how eudis reports it, which may be incorrect.
Either way, the DIV2 op checks the actual value to see if it's a double or not. I believe that the translator, however, is seeing that retval_int is declared as an integer, and assumes that it is, and so the code is optimized based on that (incorrect in this case) assumption.
The interpreter, for integer checks, converts doubles to ints to see if they are, in fact, ints. The actual representation is important for the translator, since it optimizes a lot of things based on what it knows about the actual representation.
The correct solution is probably to update the GType() function in c_decl.e to return a more correct (but slower) answer. Alternatively, we could do some extra work when assigning to an integer in the translator so that those assumptions in GType() are correct regarding declared integers. The downside to this is that there are a lot of places in the translator where this could happen.
3. Comment by mattlewis
Apr 23, 2011
Actually, the problem appears to be that no INTEGER_CHECK op is emitted when a function is inlined and the result of the function is assigned to a declared integer.
4. Comment by mattlewis
Apr 24, 2011
See: hg:euphoria/rev/353cbdd16f52
changeset: 4846:353cbdd16f52 branch: 4.0 parent: 4844:5b85af33c5dd user: Matt Lewis date: Sat Apr 23 19:15:45 2011 -0400 files: tests/t_types.e description:
- add failing test for ticket 655
5. Comment by mattlewis
Apr 24, 2011
See: hg:euphoria/rev/19a8f698b482
changeset: 4847:19a8f698b482 branch: 4.0 user: Matt Lewis date: Sun Apr 24 08:20:44 2011 -0400 files: source/parser.e description:
- Fix translator type checking. INTEGER_CHECK ops coerce doubles to ints, which is the correct behavior. This was a regression when the code was refactored.
- fixes ticket 655
6. Comment by mattlewis
Apr 24, 2011
See: hg:euphoria/rev/53cee7fa862b
changeset: 4848:53cee7fa862b branch: 4.0 user: Matt Lewis date: Sun Apr 24 08:24:44 2011 -0400 files: docs/release/4.0.3.txt description:
- release notes for ticket 655