awk: bitwise ops cast oprands and results to unsigned long,
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 28 Aug 2008 23:16:58 +0000 (23:16 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 28 Aug 2008 23:16:58 +0000 (23:16 -0000)
 not signed. closes 4774.

editors/awk.c

index 19f48401e5c18faa30aeee42d2f07d370254faa1..72eca245f0d098ae8291004b81bc0ce60bbd3761 100644 (file)
@@ -2039,28 +2039,30 @@ static var *exec_builtin(node *op, var *res)
                setvar_p(res, s);
                break;
 
+       /* Bitwise ops must assume that operands are unsigned. GNU Awk 3.1.5:
+        * awk '{ print or(-1,1) }' gives "4.29497e+09", not "-2.xxxe+09" */
        case B_an:
-               setvar_i(res, (long)getvar_i(av[0]) & (long)getvar_i(av[1]));
+               setvar_i(res, (unsigned long)getvar_i(av[0]) & (unsigned long)getvar_i(av[1]));
                break;
 
        case B_co:
-               setvar_i(res, ~(long)getvar_i(av[0]));
+               setvar_i(res, ~(unsigned long)getvar_i(av[0]));
                break;
 
        case B_ls:
-               setvar_i(res, (long)getvar_i(av[0]) << (long)getvar_i(av[1]));
+               setvar_i(res, (unsigned long)getvar_i(av[0]) << (unsigned long)getvar_i(av[1]));
                break;
 
        case B_or:
-               setvar_i(res, (long)getvar_i(av[0]) | (long)getvar_i(av[1]));
+               setvar_i(res, (unsigned long)getvar_i(av[0]) | (unsigned long)getvar_i(av[1]));
                break;
 
        case B_rs:
-               setvar_i(res, (long)((unsigned long)getvar_i(av[0]) >> (unsigned long)getvar_i(av[1])));
+               setvar_i(res, (unsigned long)getvar_i(av[0]) >> (unsigned long)getvar_i(av[1]));
                break;
 
        case B_xo:
-               setvar_i(res, (long)getvar_i(av[0]) ^ (long)getvar_i(av[1]));
+               setvar_i(res, (unsigned long)getvar_i(av[0]) ^ (unsigned long)getvar_i(av[1]));
                break;
 
        case B_lo: