Menu

#1861 expr || fails with hex data

obsolete: 8.3.4
closed-fixed
5
2002-04-26
2002-04-25
Anonymous
No

running on solaris 5.7, tcl 8.3.4 compiled with gcc
version egcs-2.91.66 19990314 (egcs-1.1.2 release)

do:
set a 0x0
set b 0
expr {$a||$b} ; # FAIL! expected boolean value but got
"0x0"

expr {0x0||0} ; # PASSES

This is astonishing, to say the least.

There appears to be some some problem with variable
expansion done by expr,
radix conversion, and short-circuiting Boolean
evaluation.

Discussion

  • miguel sofer

    miguel sofer - 2002-04-25
    • labels: --> 105682
    • assigned_to: nobody --> msofer
     
  • miguel sofer

    miguel sofer - 2002-04-25

    Logged In: YES
    user_id=148712

    I cannot reproduce this with either tcl8.3.4 (Activestate
    binary or compiled from tcl-core-8-3-1-branch) or the HEAD
    (linux, gcc 2.96).

    Can this be platform specific? Weird ...

     
  • Nobody/Anonymous

    Logged In: NO

    After msofer responded, I retried this experiment on a
    linux-x86 box
    and on my solaris boxes.
    linux-x86 works as intendend;

    solaris5.7 and solaris 5.8 fails as shown above.
    I only ran the experiment on tcl8.3.2.

     
  • Robert R. Henry

    Robert R. Henry - 2002-04-25

    Logged In: YES
    user_id=526373

    The original submitter (rrh@cray.com) now has a source forge
    account "rrh"

     
  • Robert R. Henry

    Robert R. Henry - 2002-04-25

    Logged In: YES
    user_id=526373

    here's more information:
    In a fresh tclsh8.3.2 on solaris, I do:
    set a 0x0; set b 0; expr {$a+$b}; expr {$a||$b} ; # no
    problems!A
    then in another fresh tcl8.3.2 session I do:
    set a 0x0; set b 0; expr {$a||$b} ; # FAILS!
    So the evaluation of + somehow normalizes the constant for
    ||.

     
  • miguel sofer

    miguel sofer - 2002-04-25

    Logged In: YES
    user_id=148712

    Could you please attach your unix/config.cache file to this
    report? I'm not yet sure what I'mlooking for, but it is
    probably in there ...

     
  • miguel sofer

    miguel sofer - 2002-04-25

    Logged In: YES
    user_id=148712

    I think I found the source of the bug: INST_LOR calls
    Tcl_GetBooleanFromObj(), which then calls strtod() on the
    string. Apparently, the Solaris strtod() does not handle hex
    numbers ...

    Quoting from
    http://www.redhat.com/devnet/whitepapers/solaris_port/x1609.html

    "Note: The GNU C library includes all ISO C99 functionality.
    This introduces two kinds of problems:
    a) traditionally used interfaces might be reused (example:
    the nan function, there was a nan symbol on some
    implementation denoting the NaN value);
    b) silent changes in the implementation. The latter is
    especially bad but unavoidable. One often hit problem is the
    change in strtod et.al to allow the hexadecimal
    floating-point number notation which suddenly lets strtod
    accept expressions it would not have before."

    I think I can find a workaround for this - the call to
    strtod might be premature in Tcl_GetBooleanFromObj(), or the
    the call to Tcl_GetBooleanFromObj() might be premature in
    INST_LOR; however, it will not happen tonight.

    Also, it might be a good opportunity to look for other
    hex/strtod bugs lurking in there.

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2002-04-26

    Logged In: YES
    user_id=72656

    This problem occurs on Windows2000 as well for 8.3, but not
    8.4. Same on HP-11 (bad on 8.3, ok on 8.4). I suspect
    that the WideInt stuff changed the way in which nums are
    identified in some way.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    I can't reproduce using 8.4a5 on Solaris8, but to help I
    attach the bytecode produced (the instruction offsets are a
    little odd because of how I'm doing the instrumentation)

    Command 4: "expr {$a||$b}"
    (16) loadScalar1 0 # var "a"
    (18) jumpTrue1 6 # pc 24
    (20) push1 1 # "0"
    (22) jump1 4 # pc 26
    (24) push1 3 # "1"
    (26) dup
    (27) jumpTrue1 5 # pc 32
    (29) loadScalar1 1 # var "b"
    (31) lor
    (32) done

    So, what is the problem? Is the fault coming from
    INST_JUMP_TRUE1 or INST_LOR? Actually, it doesn't really
    matter; the real problem is indeed Tcl_GetBooleanFromObj()
    (called by both those instructions) being unable to handle
    0x0 on some platforms.

    Ah! Oh. I see a problem because only strtoll() and
    strtod() are used to try to parse the string, and not
    strtol(). I'll fix this bug (which still exists on the head
    on 64-bit machines!) and backport to the 8.3 branch.

     
  • Donal K. Fellows

    • labels: 105682 --> 10. Objects
    • assigned_to: msofer --> dkf
     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    OK, I think I've got this fully fixed in both the 8.3 branch
    (which didn't handle things like 0xac at all) and in the
    HEAD (which just came unstuck on some platforms in selected
    situations.)

     
  • Donal K. Fellows

    • status: open --> closed-fixed
     
  • Don Porter

    Don Porter - 2002-04-26

    Logged In: YES
    user_id=80530

    Tcl's core-8-3-1-branch is now broken on Linux:

    cc -pipe -c -O -D__NO_STRING_INLINES -D__NO_MATH_INLINES
    -Wall -Wconversion -Wno-implicit-int -fPIC -I./../generic
    -I. -DHAVE_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DHAVE_GETCWD=1
    -DHAVE_OPENDIR=1 -DHAVE_STRSTR=1 -DHAVE_STRTOL=1
    -DHAVE_TMPNAM=1 -DHAVE_WAITPID=1 -DHAVE_UNISTD_H=1
    -DHAVE_SYS_PARAM_H=1 -DUSE_TERMIOS=1 -DHAVE_SYS_TIME_H=1
    -DTIME_WITH_SYS_TIME=1 -DHAVE_TM_ZONE=1 -DHAVE_GMTIME_R=1
    -DHAVE_LOCALTIME_R=1 -DHAVE_TM_GMTOFF=1
    -DHAVE_TIMEZONE_VAR=1 -DHAVE_ST_BLKSIZE=1 -DSTDC_HEADERS=1
    -DNEED_MATHERR=1 -DHAVE_SIGNED_CHAR=1 -DHAVE_SYS_IOCTL_H=1
    -DSTATIC_BUILD=1 -DTCL_SHLIB_EXT=\".so\"
    ./../generic/tclObj.c
    ./../generic/tclObj.c: In function `SetBooleanFromAny':
    ./../generic/tclObj.c:1059: too few arguments to function
    `strtol'
    make: *** [tclObj.o] Error 1

     
  • Don Porter

    Don Porter - 2002-04-26

    Logged In: YES
    user_id=80530

    seems it was just a missing argument typo.

    committing fix to the fix.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    Thanks for fixing that; the old brain must've been on the
    blink for me to (conceptually) copy the arguments from
    strtod() instead of strtol() in the other editor window, and
    I had to leave my office in a hurry (recarpeting!) so I
    didn't have time to get the (blindingly obvious) fix in.