[hackers] [scc] Fix readint() || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 7 Oct 2015 17:44:48 +0200 (CEST)

commit a71f0ed6bf7bac612633c2c2b745d6bf2b45d314
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Tue Oct 6 18:27:08 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Oct 7 17:23:30 2015 +0200

    Fix readint()
    
    C99 imposes crazy rules in integer constant expressions, which
    are different for decimal constants.

diff --git a/cc1/lex.c b/cc1/lex.c
index b8a246b..ad3a6b8 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -258,40 +258,44 @@ tok2str(void)
 }
 
 static Symbol *
-readint(char *s, int base, Symbol *sym)
+readint(char *s, int base, int sign, Symbol *sym)
 {
         Type *tp = sym->type;
- struct limits *lim = getlimits(tp);
+ struct limits *lim;
         TUINT u, val, max;
         int c;
 
+ lim = getlimits(tp);
         max = (tp->sign) ? lim->max.u : lim->max.i;
+ if (*s == '0')
+ ++s;
+ if (toupper(*s) == 'X')
+ ++s;
 
         for (u = 0; isxdigit(c = *s++); u = u*base + val) {
                 val = (c <= '9') ? c - '0' : 10 + c - 'A';
+ repeat:
                 if (u <= max/base && u*base <= max - val)
                         continue;
                 if (tp->sign) {
- if (tp == inttype) {
- tp = longtype;
- } else if (tp == longtype) {
- tp == llongtype;
- } else {
- errorp("overflow in integer constant");
- break;
- }
+ if (tp == inttype)
+ tp = (base==10) ? longtype : uinttype;
+ else if (tp == longtype)
+ tp = (base==10) ? llongtype : ulongtype;
+ else
+ goto overflow;
                 } else {
- if (tp == uinttype) {
- tp = ulongtype;
- } else if (tp == ulongtype) {
- tp == ullongtype;
- } else {
- errorp("overflow in integer constant");
- break;
- }
+ if (tp == uinttype)
+ tp = (sign==UNSIGNED) ? ulongtype : longtype;
+ else if (tp == ulongtype)
+ tp = (sign==UNSIGNED) ? ullongtype : llongtype;
+ else
+ goto overflow;
                 }
                 sym->type = tp;
+ lim = getlimits(tp);
                 max = (tp->sign) ? lim->max.u : lim->max.i;
+ goto repeat;
         }
 
         if (tp->sign)
_AT_@ -300,6 +304,10 @@ readint(char *s, int base, Symbol *sym)
                 sym->u.u = u;
 
         return sym;
+
+overflow:
+ errorp("overflow in integer constant");
+ return sym;
 }
 
 static unsigned
_AT_@ -333,7 +341,7 @@ convert:
         sym = newsym(NS_IDEN);
         sym->type = tp;
         sym->flags |= ISCONSTANT;
- yylval.sym = readint(s, base, sym);
+ yylval.sym = readint(s, base, sign, sym);
         return CONSTANT;
 }
 
Received on Wed Oct 07 2015 - 17:44:48 CEST

This archive was generated by hypermail 2.3.0 : Wed Oct 07 2015 - 17:48:20 CEST