/ Check-in [abf21394]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix all known instances of signed-integer overflow. Within SQL expressions, integer overflow now forces coercion to floating point. The shift operators work with any integer right-hand operand with negative values reversing the direction of the shift.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: abf21394124a0af46f072793718964cee2ce55d0
User & Date: drh 2011-03-05 20:59:46
Context
2011-03-05
21:41
Simplifications to the overflow-free multiplier. Also remove some commented-out code that was left in that subroutine by mistake on the previous check-in. check-in: 55fc25fd user: drh tags: trunk
20:59
Fix all known instances of signed-integer overflow. Within SQL expressions, integer overflow now forces coercion to floating point. The shift operators work with any integer right-hand operand with negative values reversing the direction of the shift. check-in: abf21394 user: drh tags: trunk
13:54
Fix an instance of signed arithmetic overflow and an one bit-shift overflow. Mark six other signed arithmetic overflow locations that need fixing. check-in: 04abab71 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1960   1960       int c;
  1961   1961       i64 value;
  1962   1962       const char *z = pExpr->u.zToken;
  1963   1963       assert( z!=0 );
  1964   1964       c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
  1965   1965       if( c==0 || (c==2 && negFlag) ){
  1966   1966         char *zV;
  1967         -      if( negFlag ){ value = -value; } /* CLANG */
         1967  +      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
  1968   1968         zV = dup8bytes(v, (char*)&value);
  1969   1969         sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
  1970   1970       }else{
  1971   1971   #ifdef SQLITE_OMIT_FLOATING_POINT
  1972   1972         sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
  1973   1973   #else
  1974   1974         codeReal(v, z, negFlag, iMem);

Changes to src/func.c.

  1235   1235     p = sqlite3_aggregate_context(context, sizeof(*p));
  1236   1236     type = sqlite3_value_numeric_type(argv[0]);
  1237   1237     if( p && type!=SQLITE_NULL ){
  1238   1238       p->cnt++;
  1239   1239       if( type==SQLITE_INTEGER ){
  1240   1240         i64 v = sqlite3_value_int64(argv[0]);
  1241   1241         p->rSum += v;
  1242         -      if( (p->approx|p->overflow)==0 ){
  1243         -        i64 iNewSum = p->iSum + v;    /* CLANG */
  1244         -        int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
  1245         -        int s2 = (int)(v       >> (sizeof(i64)*8-1));
  1246         -        int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
  1247         -        p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
  1248         -        p->iSum = iNewSum;
         1242  +      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
         1243  +        p->overflow = 1;
  1249   1244         }
  1250   1245       }else{
  1251   1246         p->rSum += sqlite3_value_double(argv[0]);
  1252   1247         p->approx = 1;
  1253   1248       }
  1254   1249     }
  1255   1250   }

Changes to src/printf.c.

   396    396               v = va_arg(ap,i64);
   397    397             }else if( flag_long ){
   398    398               v = va_arg(ap,long int);
   399    399             }else{
   400    400               v = va_arg(ap,int);
   401    401             }
   402    402             if( v<0 ){
   403         -            longvalue = -v;  /* CLANG */
          403  +            if( v==SMALLEST_INT64 ){
          404  +              longvalue = ((u64)1)<<63;
          405  +            }else{
          406  +              longvalue = -v;
          407  +            }
   404    408               prefix = '-';
   405    409             }else{
   406    410               longvalue = v;
   407    411               if( flag_plussign )        prefix = '+';
   408    412               else if( flag_blanksign )  prefix = ' ';
   409    413               else                       prefix = 0;
   410    414             }

Changes to src/sqliteInt.h.

  2899   2899   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
  2900   2900   CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
  2901   2901   Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
  2902   2902   Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
  2903   2903   int sqlite3CheckCollSeq(Parse *, CollSeq *);
  2904   2904   int sqlite3CheckObjectName(Parse *, const char *);
  2905   2905   void sqlite3VdbeSetChanges(sqlite3 *, int);
         2906  +int sqlite3AddInt64(i64*,i64);
         2907  +int sqlite3SubInt64(i64*,i64);
         2908  +int sqlite3MulInt64(i64*,i64);
  2906   2909   
  2907   2910   const void *sqlite3ValueText(sqlite3_value*, u8);
  2908   2911   int sqlite3ValueBytes(sqlite3_value*, u8);
  2909   2912   void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
  2910   2913                           void(*)(void*));
  2911   2914   void sqlite3ValueFree(sqlite3_value*);
  2912   2915   sqlite3_value *sqlite3ValueNew(sqlite3 *);

Changes to src/util.c.

   437    437       testcase( c==(+1) );
   438    438     }
   439    439     return c;
   440    440   }
   441    441   
   442    442   
   443    443   /*
   444         -** Convert zNum to a 64-bit signed integer and write
   445         -** the value of the integer into *pNum.
   446         -** If zNum is exactly 9223372036854665808, return 2.
   447         -** This is a special case as the context will determine
   448         -** if it is too big (used as a negative).
   449         -** If zNum is not an integer or is an integer that 
   450         -** is too large to be expressed with 64 bits,
   451         -** then return 1.  Otherwise return 0.
          444  +** Convert zNum to a 64-bit signed integer.
          445  +**
          446  +** If the zNum value is representable as a 64-bit twos-complement 
          447  +** integer, then write that value into *pNum and return 0.
          448  +**
          449  +** If zNum is exactly 9223372036854665808, return 2.  This special
          450  +** case is broken out because while 9223372036854665808 cannot be a 
          451  +** signed 64-bit integer, its negative -9223372036854665808 can be.
          452  +**
          453  +** If zNum is too big for a 64-bit integer and is not
          454  +** 9223372036854665808 then return 1.
   452    455   **
   453    456   ** length is the number of bytes in the string (bytes, not characters).
   454    457   ** The string is not necessarily zero-terminated.  The encoding is
   455    458   ** given by enc.
   456    459   */
   457    460   int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
   458    461     int incr = (enc==SQLITE_UTF8?1:2);
   459         -  i64 v = 0;
          462  +  u64 u = 0;
   460    463     int neg = 0; /* assume positive */
   461    464     int i;
   462    465     int c = 0;
   463    466     const char *zStart;
   464    467     const char *zEnd = zNum + length;
   465    468     if( enc==SQLITE_UTF16BE ) zNum++;
   466    469     while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
   467         -  if( zNum>=zEnd ) goto do_atoi_calc;
   468         -  if( *zNum=='-' ){
   469         -    neg = 1;
   470         -    zNum+=incr;
   471         -  }else if( *zNum=='+' ){
   472         -    zNum+=incr;
          470  +  if( zNum<zEnd ){
          471  +    if( *zNum=='-' ){
          472  +      neg = 1;
          473  +      zNum+=incr;
          474  +    }else if( *zNum=='+' ){
          475  +      zNum+=incr;
          476  +    }
   473    477     }
   474         -do_atoi_calc:
   475    478     zStart = zNum;
   476    479     while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
   477    480     for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
   478         -    v = v*10 + c - '0';  /* CLANG */
          481  +    u = u*10 + c - '0';
   479    482     }
   480         -  *pNum = neg ? -v : v;  /* CLANG */
          483  +  if( u>LARGEST_INT64 ){
          484  +    *pNum = SMALLEST_INT64;
          485  +  }else if( neg ){
          486  +    *pNum = -(i64)u;
          487  +  }else{
          488  +    *pNum = (i64)u;
          489  +  }
   481    490     testcase( i==18 );
   482    491     testcase( i==19 );
   483    492     testcase( i==20 );
   484    493     if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
   485    494       /* zNum is empty or contains non-numeric text or is longer
   486    495       ** than 19 digits (thus guaranteeing that it is too large) */
   487    496       return 1;
   488    497     }else if( i<19*incr ){
   489    498       /* Less than 19 digits, so we know that it fits in 64 bits */
          499  +    assert( u<=LARGEST_INT64 );
   490    500       return 0;
   491    501     }else{
   492         -    /* 19-digit numbers must be no larger than 9223372036854775807 if positive
   493         -    ** or 9223372036854775808 if negative.  Note that 9223372036854665808
   494         -    ** is 2^63. Return 1 if to large */
   495         -    c=compare2pow63(zNum, incr);
   496         -    if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
   497         -    return c<neg ? 0 : 1;
          502  +    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
          503  +    c = compare2pow63(zNum, incr);
          504  +    if( c<0 ){
          505  +      /* zNum is less than 9223372036854775808 so it fits */
          506  +      assert( u<=LARGEST_INT64 );
          507  +      return 0;
          508  +    }else if( c>0 ){
          509  +      /* zNum is greater than 9223372036854775808 so it overflows */
          510  +      return 1;
          511  +    }else{
          512  +      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
          513  +      ** special case 2 overflow if positive */
          514  +      assert( u-1==LARGEST_INT64 );
          515  +      assert( (*pNum)==SMALLEST_INT64 );
          516  +      return neg ? 0 : 2;
          517  +    }
   498    518     }
   499    519   }
   500    520   
   501    521   /*
   502    522   ** If zNum represents an integer that will fit in 32-bits, then set
   503    523   ** *pValue to that integer and return true.  Otherwise return false.
   504    524   **
................................................................................
  1056   1076       testcase( sqlite3GlobalConfig.xLog!=0 );
  1057   1077       logBadConnection("invalid");
  1058   1078       return 0;
  1059   1079     }else{
  1060   1080       return 1;
  1061   1081     }
  1062   1082   }
         1083  +
         1084  +/*
         1085  +** Attempt to add, substract, or multiply the 64-bit signed value iB against
         1086  +** the other 64-bit signed integer at *pA and store the result in *pA.
         1087  +** Return 0 on success.  Or if the operation would have resulted in an
         1088  +** overflow, leave *pA unchanged and return 1.
         1089  +*/
         1090  +int sqlite3AddInt64(i64 *pA, i64 iB){
         1091  +  i64 iA = *pA;
         1092  +  testcase( iA==0 ); testcase( iA==1 );
         1093  +  testcase( iB==-1 ); testcase( iB==0 );
         1094  +  if( iB>=0 ){
         1095  +    testcase( iA>0 && LARGEST_INT64 - iA == iB );
         1096  +    testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
         1097  +    if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
         1098  +    *pA += iB;
         1099  +  }else{
         1100  +    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
         1101  +    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
         1102  +    if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
         1103  +    *pA += iB;
         1104  +  }
         1105  +  return 0; 
         1106  +}
         1107  +int sqlite3SubInt64(i64 *pA, i64 iB){
         1108  +  testcase( iB==SMALLEST_INT64+1 );
         1109  +  if( iB==SMALLEST_INT64 ){
         1110  +    testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
         1111  +    if( (*pA)>=0 ) return 1;
         1112  +    *pA -= iB;
         1113  +    return 0;
         1114  +  }else{
         1115  +    return sqlite3AddInt64(pA, -iB);
         1116  +  }
         1117  +}
         1118  +#define TWOPOWER32 (((i64)1)<<32)
         1119  +#define TWOPOWER31 (((i64)1)<<31)
         1120  +int sqlite3MulInt64(i64 *pA, i64 iB){
         1121  +  i64 iA = *pA;
         1122  +  i64 iA1, iA0, iB1, iB0, r;
         1123  +
         1124  +//  if( iB==1 ){ return 0; }
         1125  +//  if( iA==1 ){ *pA = iB; return 0; }
         1126  +  iA1 = iA/TWOPOWER32;
         1127  +  iA0 = iA % TWOPOWER32;
         1128  +  iB1 = iB/TWOPOWER32;
         1129  +  iB0 = iB % TWOPOWER32;
         1130  +  if( iA1*iB1 != 0 ) return 1;
         1131  +  r = iA1*iB0;
         1132  +  if( sqlite3AddInt64(&r, iA0*iB1) ) return 1;
         1133  +  testcase( r==(-TWOPOWER31)-1 );
         1134  +  testcase( r==(-TWOPOWER31) );
         1135  +  testcase( r==TWOPOWER31 );
         1136  +  testcase( r==TWOPOWER31-1 );
         1137  +  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
         1138  +  r *= TWOPOWER32;
         1139  +  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
         1140  +  *pA = r;
         1141  +  return 0;
         1142  +}

Changes to src/vdbe.c.

  1242   1242     pOut = &aMem[pOp->p3];
  1243   1243     flags = pIn1->flags | pIn2->flags;
  1244   1244     if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  1245   1245     if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
  1246   1246       iA = pIn1->u.i;
  1247   1247       iB = pIn2->u.i;
  1248   1248       switch( pOp->opcode ){
  1249         -      case OP_Add:         iB += iA;       break;   /* CLANG */
  1250         -      case OP_Subtract:    iB -= iA;       break;
  1251         -      case OP_Multiply:    iB *= iA;       break;
         1249  +      case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
         1250  +      case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
         1251  +      case OP_Multiply:  if( sqlite3MulInt64(&iB,iA) ) goto fp_math;  break;
  1252   1252         case OP_Divide: {
  1253   1253           if( iA==0 ) goto arithmetic_result_is_null;
  1254         -        /* Dividing the largest possible negative 64-bit integer (1<<63) by 
  1255         -        ** -1 returns an integer too large to store in a 64-bit data-type. On
  1256         -        ** some architectures, the value overflows to (1<<63). On others,
  1257         -        ** a SIGFPE is issued. The following statement normalizes this
  1258         -        ** behavior so that all architectures behave as if integer 
  1259         -        ** overflow occurred.
  1260         -        */
  1261         -        if( iA==-1 && iB==SMALLEST_INT64 ) iA = 1;
         1254  +        if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
  1262   1255           iB /= iA;
  1263   1256           break;
  1264   1257         }
  1265   1258         default: {
  1266   1259           if( iA==0 ) goto arithmetic_result_is_null;
  1267   1260           if( iA==-1 ) iA = 1;
  1268   1261           iB %= iA;
  1269   1262           break;
  1270   1263         }
  1271   1264       }
  1272   1265       pOut->u.i = iB;
  1273   1266       MemSetTypeFlag(pOut, MEM_Int);
  1274   1267     }else{
         1268  +fp_math:
  1275   1269       rA = sqlite3VdbeRealValue(pIn1);
  1276   1270       rB = sqlite3VdbeRealValue(pIn2);
  1277   1271       switch( pOp->opcode ){
  1278   1272         case OP_Add:         rB += rA;       break;
  1279   1273         case OP_Subtract:    rB -= rA;       break;
  1280   1274         case OP_Multiply:    rB *= rA;       break;
  1281   1275         case OP_Divide: {
................................................................................
  1462   1456   ** Store the result in register P3.
  1463   1457   ** If either input is NULL, the result is NULL.
  1464   1458   */
  1465   1459   case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
  1466   1460   case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
  1467   1461   case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
  1468   1462   case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
  1469         -  i64 a;
  1470         -  i64 b;
         1463  +  i64 iA;
         1464  +  u64 uA;
         1465  +  i64 iB;
         1466  +  u8 op;
  1471   1467   
  1472   1468     pIn1 = &aMem[pOp->p1];
  1473   1469     pIn2 = &aMem[pOp->p2];
  1474   1470     pOut = &aMem[pOp->p3];
  1475   1471     if( (pIn1->flags | pIn2->flags) & MEM_Null ){
  1476   1472       sqlite3VdbeMemSetNull(pOut);
  1477   1473       break;
  1478   1474     }
  1479         -  a = sqlite3VdbeIntValue(pIn2);
  1480         -  b = sqlite3VdbeIntValue(pIn1);
  1481         -  switch( pOp->opcode ){
  1482         -    case OP_BitAnd:      a &= b;     break;
  1483         -    case OP_BitOr:       a |= b;     break;
  1484         -    case OP_ShiftLeft:   a <<= b;    break;
  1485         -    default:  assert( pOp->opcode==OP_ShiftRight );
  1486         -                         a >>= b;    break;
         1475  +  iA = sqlite3VdbeIntValue(pIn2);
         1476  +  iB = sqlite3VdbeIntValue(pIn1);
         1477  +  op = pOp->opcode;
         1478  +  if( op==OP_BitAnd ){
         1479  +    iA &= iB;
         1480  +  }else if( op==OP_BitOr ){
         1481  +    iA |= iB;
         1482  +  }else if( iB!=0 ){
         1483  +    assert( op==OP_ShiftRight || op==OP_ShiftLeft );
         1484  +
         1485  +    /* If shifting by a negative amount, shift in the other direction */
         1486  +    if( iB<0 ){
         1487  +      assert( OP_ShiftRight==OP_ShiftLeft+1 );
         1488  +      op = 2*OP_ShiftLeft + 1 - op;
         1489  +      iB = iB>(-64) ? -iB : 64;
         1490  +    }
         1491  +
         1492  +    if( iB>=64 ){
         1493  +      iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1;
         1494  +    }else{
         1495  +      memcpy(&uA, &iA, sizeof(uA));
         1496  +      if( op==OP_ShiftLeft ){
         1497  +        uA <<= iB;
         1498  +      }else{
         1499  +        uA >>= iB;
         1500  +        /* Sign-extend on a right shift of a negative number */
         1501  +        if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB);
         1502  +      }
         1503  +      memcpy(&iA, &uA, sizeof(iA));
         1504  +    }
  1487   1505     }
  1488         -  pOut->u.i = a;
         1506  +  pOut->u.i = iA;
  1489   1507     MemSetTypeFlag(pOut, MEM_Int);
  1490   1508     break;
  1491   1509   }
  1492   1510   
  1493   1511   /* Opcode: AddImm  P1 P2 * * *
  1494   1512   ** 
  1495   1513   ** Add the constant P2 to the value in register P1.

Changes to src/vdbemem.c.

   363    363     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   364    364     flags = pMem->flags;
   365    365     if( flags & MEM_Int ){
   366    366       return pMem->u.i;
   367    367     }else if( flags & MEM_Real ){
   368    368       return doubleToInt64(pMem->r);
   369    369     }else if( flags & (MEM_Str|MEM_Blob) ){
   370         -    i64 value;
          370  +    i64 value = 0;
   371    371       assert( pMem->z || pMem->n==0 );
   372    372       testcase( pMem->z==0 );
   373    373       sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
   374    374       return value;
   375    375     }else{
   376    376       return 0;
   377    377     }

Changes to test/expr.test.

    78     78   test_expr expr-1.41 {i1=1, i2=2} {-(i2+i1)} {-3}
    79     79   test_expr expr-1.42 {i1=1, i2=2} {i1|i2} {3}
    80     80   test_expr expr-1.42b {i1=1, i2=2} {4|2} {6}
    81     81   test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0}
    82     82   test_expr expr-1.43b {i1=1, i2=2} {4&5} {4}
    83     83   test_expr expr-1.44 {i1=1} {~i1} {-2}
    84     84   test_expr expr-1.44b {i1=NULL} {~i1} {{}}
    85         -test_expr expr-1.45 {i1=1, i2=3} {i1<<i2} {8}
    86         -test_expr expr-1.46 {i1=32, i2=3} {i1>>i2} {4}
           85  +test_expr expr-1.45a {i1=1, i2=3} {i1<<i2} {8}
           86  +test_expr expr-1.45b {i1=1, i2=-3} {i1>>i2} {8}
           87  +test_expr expr-1.45c {i1=1, i2=0} {i1<<i2} {1}
           88  +test_expr expr-1.45d {i1=1, i2=62} {i1<<i2} {4611686018427387904}
           89  +test_expr expr-1.45e {i1=1, i2=63} {i1<<i2} {-9223372036854775808}
           90  +test_expr expr-1.45f {i1=1, i2=64} {i1<<i2} {0}
           91  +test_expr expr-1.45g {i1=32, i2=-9223372036854775808} {i1>>i2} {0}
           92  +test_expr expr-1.46a {i1=32, i2=3} {i1>>i2} {4}
           93  +test_expr expr-1.46b {i1=32, i2=6} {i1>>i2} {0}
           94  +test_expr expr-1.46c {i1=-32, i2=3} {i1>>i2} {-4}
           95  +test_expr expr-1.46d {i1=-32, i2=100} {i1>>i2} {-1}
           96  +test_expr expr-1.46e {i1=32, i2=-3} {i1>>i2} {256}
    87     97   test_expr expr-1.47 {i1=9999999999, i2=8888888888} {i1<i2} 0
    88     98   test_expr expr-1.48 {i1=9999999999, i2=8888888888} {i1=i2} 0
    89     99   test_expr expr-1.49 {i1=9999999999, i2=8888888888} {i1>i2} 1
    90    100   test_expr expr-1.50 {i1=99999999999, i2=99999999998} {i1<i2} 0
    91    101   test_expr expr-1.51 {i1=99999999999, i2=99999999998} {i1=i2} 0
    92    102   test_expr expr-1.52 {i1=99999999999, i2=99999999998} {i1>i2} 1
    93    103   test_expr expr-1.53 {i1=099999999999, i2=99999999999} {i1<i2} 0
................................................................................
   150    160   ifcapable floatingpoint {
   151    161     test_expr expr-1.103 {i1=0} {(-2147483648.0 % -1)} 0.0
   152    162     test_expr expr-1.104 {i1=0} {(-9223372036854775808.0 % -1)} 0.0
   153    163     test_expr expr-1.105 {i1=0} {(-9223372036854775808.0 / -1)>1} 1
   154    164   }
   155    165   
   156    166   if {[working_64bit_int]} {
   157         -  test_expr expr-1.106 {i1=0} {(1<<63)/-1} -9223372036854775808
          167  +  test_expr expr-1.106 {i1=0} {-9223372036854775808/-1} 9.22337203685478e+18
   158    168   }
   159    169   
   160         -test_expr expr-1.107 {i1=0} {(1<<63)%-1} 0
          170  +test_expr expr-1.107 {i1=0} {-9223372036854775808%-1} 0
   161    171   test_expr expr-1.108 {i1=0} {1%0} {{}}
   162    172   test_expr expr-1.109 {i1=0} {1/0} {{}}
   163    173   
   164    174   if {[working_64bit_int]} {
   165    175     test_expr expr-1.110 {i1=0} {-9223372036854775807/-1} 9223372036854775807
   166    176   }
   167    177   
................................................................................
   185    195     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
   186    196   test_expr expr-1.124 {i1=NULL, i2=NULL} \
   187    197     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
   188    198   test_expr expr-1.125 {i1=6, i2=NULL} \
   189    199     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
   190    200   test_expr expr-1.126 {i1=8, i2=8} \
   191    201     {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
          202  +
          203  +ifcapable floatingpoint {if {[working_64bit_int]} {
          204  +  test_expr expr-1.200\
          205  +      {i1=9223372036854775806, i2=1} {i1+i2}      9223372036854775807
          206  +  test_expr expr-1.201\
          207  +      {i1=9223372036854775806, i2=2} {i1+i2}      9.22337203685478e+18
          208  +  test_expr expr-1.202\
          209  +      {i1=9223372036854775806, i2=100000} {i1+i2} 9.22337203685488e+18
          210  +  test_expr expr-1.203\
          211  +      {i1=9223372036854775807, i2=0} {i1+i2}      9223372036854775807
          212  +  test_expr expr-1.204\
          213  +      {i1=9223372036854775807, i2=1} {i1+i2}      9.22337203685478e+18
          214  +  test_expr expr-1.205\
          215  +      {i2=9223372036854775806, i1=1} {i1+i2}      9223372036854775807
          216  +  test_expr expr-1.206\
          217  +      {i2=9223372036854775806, i1=2} {i1+i2}      9.22337203685478e+18
          218  +  test_expr expr-1.207\
          219  +      {i2=9223372036854775806, i1=100000} {i1+i2} 9.22337203685488e+18
          220  +  test_expr expr-1.208\
          221  +      {i2=9223372036854775807, i1=0} {i1+i2}      9223372036854775807
          222  +  test_expr expr-1.209\
          223  +      {i2=9223372036854775807, i1=1} {i1+i2}      9.22337203685478e+18
          224  +  test_expr expr-1.210\
          225  +      {i1=-9223372036854775807, i2=-1} {i1+i2}    -9223372036854775808
          226  +  test_expr expr-1.211\
          227  +      {i1=-9223372036854775807, i2=-2} {i1+i2}    -9.22337203685478e+18
          228  +  test_expr expr-1.212\
          229  +      {i1=-9223372036854775807, i2=-100000} {i1+i2} -9.22337203685488e+18
          230  +  test_expr expr-1.213\
          231  +      {i1=-9223372036854775808, i2=0} {i1+i2}     -9223372036854775808
          232  +  test_expr expr-1.214\
          233  +      {i1=-9223372036854775808, i2=-1} {i1+i2}    -9.22337203685478e+18
          234  +  test_expr expr-1.215\
          235  +      {i2=-9223372036854775807, i1=-1} {i1+i2}    -9223372036854775808
          236  +  test_expr expr-1.216\
          237  +      {i2=-9223372036854775807, i1=-2} {i1+i2}    -9.22337203685478e+18
          238  +  test_expr expr-1.217\
          239  +      {i2=-9223372036854775807, i1=-100000} {i1+i2} -9.22337203685488e+18
          240  +  test_expr expr-1.218\
          241  +      {i2=-9223372036854775808, i1=0} {i1+i2}     -9223372036854775808
          242  +  test_expr expr-1.219\
          243  +      {i2=-9223372036854775808, i1=-1} {i1+i2}    -9.22337203685478e+18
          244  +  test_expr expr-1.220\
          245  +      {i1=9223372036854775806, i2=-1} {i1-i2}     9223372036854775807
          246  +  test_expr expr-1.221\
          247  +      {i1=9223372036854775806, i2=-2} {i1-i2}      9.22337203685478e+18
          248  +  test_expr expr-1.222\
          249  +      {i1=9223372036854775806, i2=-100000} {i1-i2} 9.22337203685488e+18
          250  +  test_expr expr-1.223\
          251  +      {i1=9223372036854775807, i2=0} {i1-i2}      9223372036854775807
          252  +  test_expr expr-1.224\
          253  +      {i1=9223372036854775807, i2=-1} {i1-i2}      9.22337203685478e+18
          254  +  test_expr expr-1.225\
          255  +      {i2=-9223372036854775806, i1=1} {i1-i2}      9223372036854775807
          256  +  test_expr expr-1.226\
          257  +      {i2=-9223372036854775806, i1=2} {i1-i2}      9.22337203685478e+18
          258  +  test_expr expr-1.227\
          259  +      {i2=-9223372036854775806, i1=100000} {i1-i2} 9.22337203685488e+18
          260  +  test_expr expr-1.228\
          261  +      {i2=-9223372036854775807, i1=0} {i1-i2}      9223372036854775807
          262  +  test_expr expr-1.229\
          263  +      {i2=-9223372036854775807, i1=1} {i1-i2}      9.22337203685478e+18
          264  +  test_expr expr-1.230\
          265  +      {i1=-9223372036854775807, i2=1} {i1-i2}    -9223372036854775808
          266  +  test_expr expr-1.231\
          267  +      {i1=-9223372036854775807, i2=2} {i1-i2}    -9.22337203685478e+18
          268  +  test_expr expr-1.232\
          269  +      {i1=-9223372036854775807, i2=100000} {i1-i2} -9.22337203685488e+18
          270  +  test_expr expr-1.233\
          271  +      {i1=-9223372036854775808, i2=0} {i1-i2}     -9223372036854775808
          272  +  test_expr expr-1.234\
          273  +      {i1=-9223372036854775808, i2=1} {i1-i2}    -9.22337203685478e+18
          274  +  test_expr expr-1.235\
          275  +      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
          276  +  test_expr expr-1.236\
          277  +      {i2=9223372036854775807, i1=-2} {i1-i2}    -9.22337203685478e+18
          278  +  test_expr expr-1.237\
          279  +      {i2=9223372036854775807, i1=-100000} {i1-i2} -9.22337203685488e+18
          280  +  test_expr expr-1.238\
          281  +      {i2=9223372036854775807, i1=0} {i1-i2}     -9223372036854775807
          282  +  test_expr expr-1.239\
          283  +      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
          284  +
          285  +  test_expr expr-1.250\
          286  +      {i1=4294967296, i2=2147483648} {i1*i2}      9.22337203685478e+18
          287  +  test_expr expr-1.251\
          288  +      {i1=4294967296, i2=2147483647} {i1*i2}      9223372032559808512
          289  +  test_expr expr-1.252\
          290  +      {i1=-4294967296, i2=2147483648} {i1*i2}     -9223372036854775808
          291  +  test_expr expr-1.253\
          292  +      {i1=-4294967296, i2=2147483647} {i1*i2}     -9223372032559808512
          293  +  test_expr expr-1.254\
          294  +      {i1=4294967296, i2=-2147483648} {i1*i2}     -9223372036854775808
          295  +  test_expr expr-1.255\
          296  +      {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
          297  +  test_expr expr-1.256\
          298  +      {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
          299  +  test_expr expr-1.257\
          300  +      {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512
          301  +
          302  +}}
   192    303   
   193    304   ifcapable floatingpoint {
   194    305     test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
   195    306     test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
   196    307     test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
   197    308   }
   198    309   set tcl_precision 15