- VarAdd, VarMul: I4 overflows to R8 and not I8 even if the result

would fit in I8. Fix tests.
- Document a brokeness in the handling of I8 numbers in
  VarNumFromParseNum. Fix tests.
This commit is contained in:
Michael Stefaniuc 2005-08-23 09:33:37 +00:00 committed by Alexandre Julliard
parent ba69174042
commit 4d36546c07
2 changed files with 28 additions and 19 deletions

View File

@ -1187,7 +1187,10 @@ static void test_VarNumFromParseNum(void)
SETRGB(12, 0xf); SETRGB(13, 0xf); SETRGB(14, 0xf); SETRGB(15, 0xf);
if (HAVE_OLEAUT32_I8)
{
CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I8(0x7fffffff,0xffffffff);
/* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
truncate the number to the smallest integer size requested:
CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I1((signed char)0xff); */
CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x7fffffff,0xffffffff);
}
/* Assume the above pattern holds for numbers without hi-bit set, test (preservation of) hi-bit */
@ -1210,7 +1213,11 @@ static void test_VarNumFromParseNum(void)
SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
if (HAVE_OLEAUT32_I8)
{
CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I8(0x80000000,0x00000002);
/* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
truncate the number to the smallest integer size requested:
CONVERT(16,0,0,16,4,0, INTEGER_VTBITS & ~VTBIT_I1);
EXPECT_I2((signed short)0x0002); */
CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
}
/* Test (preservation of) hi-bit with STRICT type requesting */
@ -4684,15 +4691,9 @@ static void test_VarMul(void)
VARMUL(I2, I2_MAX, I2, I2_MAX, I4, I2_MAX * I2_MAX);
VARMUL(I2, I2_MAX, I2, I2_MIN, I4, I2_MAX * I2_MIN);
VARMUL(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN * I2_MIN);
if (HAVE_OLEAUT32_I8) {
VARMUL(I4, I4_MAX, I4, I4_MAX, I8, (LONGLONG)I4_MAX * I4_MAX);
VARMUL(I4, I4_MAX, I4, I4_MIN, I8, (LONGLONG)I4_MAX * I4_MIN);
VARMUL(I4, I4_MIN, I4, I4_MIN, I8, (LONGLONG)I4_MIN * I4_MIN);
} else {
VARMUL(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX * I4_MAX);
VARMUL(I4, I4_MAX, I4, I4_MIN, R8, (double)I4_MAX * I4_MIN);
VARMUL(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN * I4_MIN);
}
VARMUL(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX * R4_MAX);
VARMUL(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX * R4_MIN);
VARMUL(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN * R4_MIN);
@ -4878,13 +4879,8 @@ static void test_VarAdd(void)
VARADD(I2, I2_MAX, I2, I2_MIN, I2, I2_MAX + I2_MIN);
VARADD(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN + I2_MIN);
VARADD(I4, I4_MAX, I4, I4_MIN, I4, I4_MAX + I4_MIN);
if (HAVE_OLEAUT32_I8) {
VARADD(I4, I4_MAX, I4, I4_MAX, I8, (LONGLONG)I4_MAX + I4_MAX);
VARADD(I4, I4_MIN, I4, I4_MIN, I8, (LONGLONG)I4_MIN + I4_MIN);
} else {
VARADD(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX + I4_MAX);
VARADD(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN + I4_MIN);
}
VARADD(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX + I4_MAX);
VARADD(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN + I4_MIN);
VARADD(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX + R4_MAX);
VARADD(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX + R4_MIN);
VARADD(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN + R4_MIN);

View File

@ -1926,6 +1926,11 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
* - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8()
* for details of the rounding method.
* - pVarDst is not cleared before the result is stored in it.
* - WinXP and Win2003 support VTBIT_I8, VTBIT_UI8 but that's buggy (by
* design?): If some other VTBIT's for integers are specified together
* with VTBIT_I8 and the number will fit only in a VT_I8 Windows will "cast"
* the number to the smallest requested integer truncating this way the
* number. Wine dosn't implement this "feature" (yet?).
*/
HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
ULONG dwVtBits, VARIANT *pVarDst)
@ -2893,8 +2898,12 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
}
if (resvt != tvt) {
if ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
/* Overflow! Change to the vartype with the next higher priority */
resvt = prio2vt[coerce[resvt] + 1];
/* Overflow! Change to the vartype with the next higher priority.
With one exception: I4 ==> R8 even if it would fit in I8 */
if (resvt == VT_I4)
resvt = VT_R8;
else
resvt = prio2vt[coerce[resvt] + 1];
hres = VariantChangeType(result, &tv, 0, resvt);
}
} else
@ -3061,8 +3070,12 @@ HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
}
if (resvt != tvt) {
while ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
/* Overflow! Change to the vartype with the next higher priority */
resvt = prio2vt[coerce[resvt] + 1];
/* Overflow! Change to the vartype with the next higher priority.
With one exception: I4 ==> R8 even if it would fit in I8 */
if (resvt == VT_I4)
resvt = VT_R8;
else
resvt = prio2vt[coerce[resvt] + 1];
}
} else
hres = VariantCopy(result, &tv);