changed name of some identifiers to more accurately represent their
authorceriel <none@none>
Tue, 8 Aug 1989 09:11:32 +0000 (09:11 +0000)
committerceriel <none@none>
Tue, 8 Aug 1989 09:11:32 +0000 (09:11 +0000)
meaning, and fixed a problem with sometimes not detecting overflow in
constants

lang/m2/comp/LLlex.c
lang/m2/comp/const.h
lang/m2/comp/cstoper.c
lang/m2/comp/type.H
lang/m2/comp/type.c

index 39b0790..e134056 100644 (file)
@@ -458,7 +458,7 @@ again:
                                /* Fall through */
                                
                        case End: {
-                               int sgnswtch = 0;
+                               int ovfl = 0;
 
                                *np = '\0';
                                if (np >= &buf[NUMSIZE]) {
@@ -466,11 +466,19 @@ again:
                                        lexerror("constant too long");
                                }
                                else {
+                                       /* The upperbound will be the same as
+                                          when computed with something like
+                                          max(unsigned long) / base (when base
+                                          is even). The problem is that
+                                          unsigned long or unsigned arith is
+                                          not accepted by all compilers
+                                       */
+                                       arith ubound = max_int[sizeof(arith)]
+                                                       / (base >> 1);
                                        np = &buf[1];
                                        while (*np == '0') np++;
                                        tk->TOK_INT = 0;
                                        while (*np) {
-                                               arith old = tk->TOK_INT;
                                                int c;
 
                                                if (is_dig(*np)) {
@@ -480,38 +488,46 @@ again:
                                                        assert(is_hex(*np));
                                                        c = *np++ - 'A' + 10;
                                                }
-                                               tk->TOK_INT = tk->TOK_INT*base
-                                                       + c;
-                                               sgnswtch += (old < 0) ^
-                                                           (tk->TOK_INT < 0);
+                                               if (tk->TOK_INT < 0 ||
+                                                   tk->TOK_INT > ubound) {
+                                                       ovfl++;
+                                               }
+                                               tk->TOK_INT = tk->TOK_INT*base;
+                                               if (tk->TOK_INT < 0 &&
+                                                   tk->TOK_INT + c >= 0) {
+                                                       ovfl++;
+                                               }
+                                               tk->TOK_INT += c;
                                        }
                                }
                                toktype = card_type;
-                               if (sgnswtch >= 2) {
-lexwarning(W_ORDINARY, "overflow in constant");
-                               }
-                               else if (ch == 'C' && base == 8) {
+                               if (ch == 'C' && base == 8) {
                                        toktype = char_type;
-                                       if (sgnswtch != 0 || tk->TOK_INT>255) {
+                                       if (ovfl != 0 || tk->TOK_INT>255 ||
+                                           tk->TOK_INT < 0) {
 lexwarning(W_ORDINARY, "character constant out of range");
                                        }
+                                       return tk->tk_symb = INTEGER;
                                }
-                               else if (ch == 'D' && base == 10) {
-                                       if (sgnswtch != 0 ||
-                                           tk->TOK_INT > max_int[(int)long_size]) {
-lexwarning(W_ORDINARY, "overflow in constant");
+                               if (ch == 'D' && base == 10) {
+                                       if (ovfl != 0 ||
+                                           tk->TOK_INT > max_int[(int)long_size] ||
+                                           tk->TOK_INT < 0) {
+                                               ovfl = 1;
                                        }
                                        toktype = longint_type;
                                }
-                               else if (sgnswtch == 0 &&
+                               else if (ovfl == 0 && tk->TOK_INT >= 0 &&
                                         tk->TOK_INT<=max_int[(int)int_size]) {
                                        toktype = intorcard_type;
                                }
                                else if (! chk_bounds(tk->TOK_INT,
                                                      full_mask[(int)int_size],
                                                      T_CARDINAL)) {
-lexwarning(W_ORDINARY, "overflow in constant");
+                                                       ovfl = 1;
                                }
+                               if (ovfl)
+lexwarning(W_ORDINARY, "overflow in constant");
                                return tk->tk_symb = INTEGER;
                                }
 
index 9c7f590..4aa261a 100644 (file)
@@ -9,9 +9,7 @@
 
 /* $Header$ */
 
-extern long
-       mach_long_sign; /* sign bit of the machine long */
-extern int
-       mach_long_size; /* size of long on this machine == sizeof(long) */
+#define        arith_sign      ((arith) (1L << (sizeof(arith) * 8 - 1)))
+
 extern unsigned int
        wrd_bits;       /* Number of bits in a word */
index 0ee16fa..def4c48 100644 (file)
 #include       "Lpars.h"
 #include       "standards.h"
 #include       "warning.h"
+#include       "const.h"
 
-long mach_long_sign;   /* sign bit of the machine long */
-int mach_long_size;    /* size of long on this machine == sizeof(long) */
-long full_mask[MAXSIZE];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */
-long max_int[MAXSIZE]; /* max_int[1] == 0x7F, max_int[2] == 0x7FFF, .. */
-long min_int[MAXSIZE]; /* min_int[1] == 0xFFFFFF80, min_int[2] = 0xFFFF8000,
+arith full_mask[MAXSIZE];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */
+arith max_int[MAXSIZE];        /* max_int[1] == 0x7F, max_int[2] == 0x7FFF, .. */
+arith min_int[MAXSIZE];        /* min_int[1] == 0xFFFFFF80, min_int[2] = 0xFFFF8000,
                           ...
                        */
 unsigned int wrd_bits; /* number of bits in a word */
@@ -68,7 +67,7 @@ cstunary(expp)
                expression below it, and the result restored in expp.
        */
        register t_node *right = expp->nd_right;
-       arith o1 = right->nd_INT;
+       register arith o1 = right->nd_INT;
 
        switch(expp->nd_symb) {
        /* Should not get here
@@ -77,9 +76,9 @@ cstunary(expp)
        */
 
        case '-':
-               if (o1 == min_int[(int)(right->nd_type->tp_size)])
+               if (o1 == min_int[(int)(right->nd_type->tp_size)]) {
                        overflow(expp);
-               
+               }
                o1 = -o1;
                break;
 
@@ -110,10 +109,10 @@ divide(pdiv, prem)
                think on C compilers which do not have
                unsigned long.
        */
-       if (o2 & mach_long_sign)        {/* o2 > max_long */
+       if (o2 & arith_sign)    {/* o2 > max_arith */
                if (! (o1 >= 0 || o1 < o2)) {
                        /*      this is the unsigned test
-                               o1 < o2 for o2 > max_long
+                               o1 < o2 for o2 > max_arith
                        */
                        *prem = o2 - o1;
                        *pdiv = 1;
@@ -122,14 +121,14 @@ divide(pdiv, prem)
                        *pdiv = 0;
                }
        }
-       else    {               /* o2 <= max_long */
-               long half, bit, hdiv, hrem, rem;
+       else    {               /* o2 <= max_arith */
+               arith half, bit, hdiv, hrem, rem;
 
-               half = (o1 >> 1) & ~mach_long_sign;
+               half = (o1 >> 1) & ~arith_sign;
                bit = o1 & 01;
                /*      now o1 == 2 * half + bit
-                       and half <= max_long
-                       and bit <= max_long
+                       and half <= max_arith
+                       and bit <= max_arith
                */
                hdiv = half / o2;
                hrem = half % o2;
@@ -138,7 +137,7 @@ divide(pdiv, prem)
                *prem = rem;
                if (rem < 0 || rem >= o2) {
                        /*      that is the unsigned compare
-                               rem >= o2 for o2 <= max_long
+                               rem >= o2 for o2 <= max_arith
                        */
                        *pdiv += 1;
                        *prem -= o2;
@@ -153,8 +152,8 @@ cstibin(expp)
                expressions below it, and the result restored in expp.
                This version is for INTEGER expressions.
        */
-       arith o1 = expp->nd_left->nd_INT;
-       arith o2 = expp->nd_right->nd_INT;
+       register arith o1 = expp->nd_left->nd_INT;
+       register arith o2 = expp->nd_right->nd_INT;
        register int sz = expp->nd_type->tp_size;
 
        assert(expp->nd_class == Oper);
@@ -184,7 +183,17 @@ cstibin(expp)
                        node_error(expp, "division by 0");
                        return;
                }
-               o1 /= o2;       /* ??? */
+#if (-1)/2==0
+               o1 /= o2;
+#else
+               if (o1 == 0) break;
+               if ((o1 < 0) != (o2 < 0)) {
+                       o1 = o1/o2 + 1;
+               }
+               else {
+                       o1 /= o2;
+               }
+#endif
                break;
 
        case MOD:
@@ -192,7 +201,17 @@ cstibin(expp)
                        node_error(expp, "modulo by 0");
                        return;
                }
-               o1 %= o2;       /* ??? */
+#if (-1)/2==0
+               o1 %= o2;
+#else
+               if (o1 == 0) break;
+               if ((o1 < 0) != (o2 < 0)) {
+                       o1 -= (o1 / o2 + 1) * o2;
+               }
+               else {
+                       o1 %= o2;
+               }
+#endif
                break;
 
        case '+':
@@ -549,7 +568,7 @@ CutSize(expr)
                expr->nd_INT &= full_mask[(int)(tp->tp_size)];
        }
        else {
-               int nbits = (int) (mach_long_size - tp->tp_size) * 8;
+               int nbits = (int) (sizeof(arith) - tp->tp_size) * 8;
 
                expr->nd_INT = (expr->nd_INT << nbits) >> nbits;
        }
@@ -566,14 +585,12 @@ InitCst()
                if (i == MAXSIZE)
                        fatal("array full_mask too small for this machine");
                full_mask[i] = bt;
-               max_int[i] = bt & ~(1L << ((i << 3) - 1));
+               max_int[i] = bt & ~(1L << ((8 * i) - 1));
                min_int[i] = - max_int[i];
                if (! options['s']) min_int[i]--;
        }
-       mach_long_size = i;
-       mach_long_sign = 1L << (mach_long_size * 8 - 1);
-       if (long_size > mach_long_size) {
-               fatal("sizeof (long) insufficient on this machine");
+       if ((int)long_size > sizeof(arith)) {
+               fatal("sizeof (arith) insufficient on this machine");
        }
 
        wrd_bits = 8 * (int) word_size;
index 753d4d8..417d70f 100644 (file)
@@ -234,8 +234,8 @@ extern t_type
 #define IsBigParamTp(tpx)      (0)
 #endif PASS_BIG_VAL_AS_VAR
 
-extern long full_mask[];
-extern long max_int[];
-extern long min_int[];
+extern arith full_mask[];
+extern arith max_int[];
+extern arith min_int[];
 
 #define ufit(n, i)     (((n) & ~full_mask[(i)]) == 0)
index 64da373..7510cb5 100644 (file)
@@ -298,9 +298,9 @@ chk_bounds(l1, l2, fund)
        if (fund == T_INTEGER) {
                return l2 >= l1;
        }
-       return (l2 & mach_long_sign ?
-               (l1 & mach_long_sign ? l2 >= l1 : 1) :
-               (l1 & mach_long_sign ? 0 : l2 >= l1)
+       return (l2 & arith_sign ?
+               (l1 & arith_sign ? l2 >= l1 : 1) :
+               (l1 & arith_sign ? 0 : l2 >= l1)
               );
 }