Fossil SCM
The th1-expr-3 test revealed that Th_SetResultInt() could produce incorrect result for INT_MIN. Ensure that -1*iVal is positive for all values and remove unsiged casts. Seems a common optimisation problem with gcc on various verisons from 10 through 13 on Linux, NetBSD and OmniOS on various architectures.
Commit
4a98d2aae1b6cc47ebd97886e6948d7c4374a7e24a11d24315b8e3de904a8bce
Parent
a8b6fdc83e8b539…
1 file changed
+5
-4
M
src/th.c
+5
-4
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -2870,21 +2870,22 @@ | ||
| 2870 | 2870 | ** Set the result of the interpreter to the th1 representation of |
| 2871 | 2871 | ** the integer iVal and return TH_OK. |
| 2872 | 2872 | */ |
| 2873 | 2873 | int Th_SetResultInt(Th_Interp *interp, int iVal){ |
| 2874 | 2874 | int isNegative = 0; |
| 2875 | + unsigned int uVal = iVal; | |
| 2875 | 2876 | char zBuf[32]; |
| 2876 | 2877 | char *z = &zBuf[32]; |
| 2877 | 2878 | |
| 2878 | 2879 | if( iVal<0 ){ |
| 2879 | 2880 | isNegative = 1; |
| 2880 | - iVal = iVal * -1; | |
| 2881 | + uVal = iVal * -1; | |
| 2881 | 2882 | } |
| 2882 | 2883 | *(--z) = '\0'; |
| 2883 | - *(--z) = (char)(48+((unsigned)iVal%10)); | |
| 2884 | - while( (iVal = ((unsigned)iVal/10))>0 ){ | |
| 2885 | - *(--z) = (char)(48+((unsigned)iVal%10)); | |
| 2884 | + *(--z) = (char)(48+(uVal%10)); | |
| 2885 | + while( (uVal = (uVal/10))>0 ){ | |
| 2886 | + *(--z) = (char)(48+(uVal%10)); | |
| 2886 | 2887 | assert(z>zBuf); |
| 2887 | 2888 | } |
| 2888 | 2889 | if( isNegative ){ |
| 2889 | 2890 | *(--z) = '-'; |
| 2890 | 2891 | } |
| 2891 | 2892 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2870,21 +2870,22 @@ | |
| 2870 | ** Set the result of the interpreter to the th1 representation of |
| 2871 | ** the integer iVal and return TH_OK. |
| 2872 | */ |
| 2873 | int Th_SetResultInt(Th_Interp *interp, int iVal){ |
| 2874 | int isNegative = 0; |
| 2875 | char zBuf[32]; |
| 2876 | char *z = &zBuf[32]; |
| 2877 | |
| 2878 | if( iVal<0 ){ |
| 2879 | isNegative = 1; |
| 2880 | iVal = iVal * -1; |
| 2881 | } |
| 2882 | *(--z) = '\0'; |
| 2883 | *(--z) = (char)(48+((unsigned)iVal%10)); |
| 2884 | while( (iVal = ((unsigned)iVal/10))>0 ){ |
| 2885 | *(--z) = (char)(48+((unsigned)iVal%10)); |
| 2886 | assert(z>zBuf); |
| 2887 | } |
| 2888 | if( isNegative ){ |
| 2889 | *(--z) = '-'; |
| 2890 | } |
| 2891 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2870,21 +2870,22 @@ | |
| 2870 | ** Set the result of the interpreter to the th1 representation of |
| 2871 | ** the integer iVal and return TH_OK. |
| 2872 | */ |
| 2873 | int Th_SetResultInt(Th_Interp *interp, int iVal){ |
| 2874 | int isNegative = 0; |
| 2875 | unsigned int uVal = iVal; |
| 2876 | char zBuf[32]; |
| 2877 | char *z = &zBuf[32]; |
| 2878 | |
| 2879 | if( iVal<0 ){ |
| 2880 | isNegative = 1; |
| 2881 | uVal = iVal * -1; |
| 2882 | } |
| 2883 | *(--z) = '\0'; |
| 2884 | *(--z) = (char)(48+(uVal%10)); |
| 2885 | while( (uVal = (uVal/10))>0 ){ |
| 2886 | *(--z) = (char)(48+(uVal%10)); |
| 2887 | assert(z>zBuf); |
| 2888 | } |
| 2889 | if( isNegative ){ |
| 2890 | *(--z) = '-'; |
| 2891 | } |
| 2892 |