Tcl Source Code

View Ticket
Login
Ticket UUID: 868489
Title: Incorrect promotion of int to wide
Type: Support Version: None
Submitter: kennykb Created on: 2003-12-31 16:09:54
Subsystem: None Assigned To: dkf
Priority: 7 High Severity:
Status: Closed Last Modified: 2009-07-29 19:41:11
Resolution: Closed By: dkf
    Closed on: 2004-09-10 21:53:23
Description:
Consider the following:

set x -2366755200
string is integer $x
set y [expr { wide($x) }]

The value of y that results is 1928212096

The problem is that the generated code for
the expression sees the "integer" internal
representation and uses it, even though
reconverting the string rep would yield a
different value.  The particular code in
question is in the "ExprCallMathFunc"
function in tclExecute.c, but the problem
appears to be pretty pervasive.

It appears to be incorrect to promote an
"integer" to a "wide" if the "integer" has a
string representation.
User Comments: dkf added on 2009-07-29 19:41:11:

IP - Comment Removed: 130.88.1.31

dkf added on 2008-11-02 18:31:57:

data_type - 210894

dkf added on 2004-09-16 15:17:34:
Logged In: YES 
user_id=79902

Oh, I see you fixed it already. :} And I see it was a simple
fix. And I see that the reason I didn't find it in testing
was endianness. Oh well.. Thanks for finding it.

dkf added on 2004-09-16 14:10:52:
Logged In: YES 
user_id=79902

And it closed another bug (I've already forgotten the
number) at the same time. Track the problem in 1027690...

dgp added on 2004-09-14 23:03:11:
Logged In: YES 
user_id=80530


Patch appears to have created
new Bug 1027690.

dkf added on 2004-09-11 04:53:23:
Logged In: YES 
user_id=79902

Patch looked just about good enough to me
Applied to HEAD and 8.4 branch

dkf added on 2004-04-23 15:23:12:
Logged In: YES 
user_id=79902

Of course that code is my code.  How do you think I know it
is a mess?  :^/

I can't check the code right now; my sandbox has other toys
in it (TIP#143 implementation as it happens) and I don't
want to get them mixed up.  If/when I get that out of the
way, I'll be able to work on this area in more detail.

kennykb added on 2004-04-23 02:05:40:
Logged In: YES 
user_id=99768

Uhm, Donal, much of that appears to be *your* code. :)

Nevertheless, I took a few quick trolls through TEBC, and
didn't see any *obvious* problems - all the code that
accesses objPtr->internalRep.longValue seems to check
the type first; likewise for wideValue.

Emphasis on 'obvious' is intentional.

dkf added on 2004-04-22 02:59:47:
Logged In: YES 
user_id=79902

That patch looks comparatively likely.  What is the impact
of this sort of treatment on number handling in TEBC and its
helpers?  I know that that code is *not* very clean, so it
might get quite surprised...

kennykb added on 2004-04-22 02:25:37:

File Added - 84569: 868489.patch

Logged In: YES 
user_id=99768

It occurs to me that the easiest way to mark that the
annoying overflow has occurred is simply to make it a
wide integer instead of an ordinary one.

The attached patch does the following:

Makes Tcl_GetIntFromObj and Tcl_GetLongFromObj
check for tclWideIntType as well as tclIntType, and do
direct conversion of the intenal rep from wide to int
(with a range check).  Also changes the conversion from
string to a new SetIntOrWideFromAny.

The new SetIntOrWideFromAny is just like the old
SetIntFromAny except that it checks for integer overflow
and uses a tclWideIntType instead of a tclIntType
for values that don't fit in a 'long' - avoiding inconsistent
internal reps.

The existing SetIntFromAny has its range checks tightened
to avoid setting an internal representation that is
inconsistent with the string rep (an error is thrown instead).

There are potential incompatibilities here because of the
tightened range in SetIntFromAny and the fact that
Tcl_GetIntFromObj is no longer guaranteed to leave a
specific internal representation.  It is arguable that any
code that runs afoul of either incompatibility is buggy
anyway.

New test cases provided for the obvious problem spots.

kennykb added on 2004-01-21 01:58:52:
Logged In: YES 
user_id=99768

The given test case works in Tcl up until the change:
2003-04-11  Don Porter  <[email protected]>

* generic/tclCmdMZ.c (Tcl_StringObjCmd,STR_IS_INT):  Corrected
inconsistent results of [string is integer] observed on systems
where sizeof(long) != sizeof(int).  [Bug 718878]
* tests/string.test: Added tests for Bug 718878.
* doc/string.n: Clarified that [string is integer] accepts
32-bit integers.

But this change is an innocent victim; replacing [string is
integer] with [clock format] will tickle the bug in earlier
releases.

dkf added on 2004-01-20 05:28:22:
Logged In: YES 
user_id=79902

The problem is how to fix this; how to detect that we are in
an "annoying integer overflow" situation and mark the object
so that we know when converting to wide to go from the
string version and not the internal rep (which would
otherwise be far faster.)

:^/ At best, this is a huge amount of work to fix.  (New
arithmetic object types require action in ever so many
places!)  I don't think I'm likely to have the free time to
take this on in the near future, so if anyone wishes to have
a go, please feel free!

kennykb added on 2004-01-05 22:49:10:
Logged In: YES 
user_id=99768

[string is integer] was just an example.  The code that first
tripped over the bug actually used [clock format].  It fails on
anything that gets into SetIntFromAny.

dkf added on 2004-01-05 22:27:33:
Logged In: YES 
user_id=79902

Why is [string is integer] setting the type of the object?

Attachments: