| @@ -2012,7 +2012,8 @@ static void parse_number(const char *p) · 2011 unmodified lines |
| 2012 | 2012 | } |
| 2013 | 2013 | } else { |
| 2014 | 2014 | unsigned long long n, n1; |
| 2015 | | − int lcount, ucount; |
| 2015 | + int lcount, ucount, must_64bit; |
| 2016 | + const char *p1; |
| 2016 | 2017 | |
| 2017 | 2018 | /* integer number */ |
| 2018 | 2019 | *q = '\0'; |
| @@ -2025,17 +2026,16 @@ static void parse_number(const char *p) · 6 unmodified lines |
| 2025 | 2026 | while(1) { |
| 2026 | 2027 | t = *q++; |
| 2027 | 2028 | /* no need for checks except for base 10 / 8 errors */ |
| 2028 | | − if (t == '\0') { |
| 2029 | + if (t == '\0') |
| 2029 | 2030 | break; |
| 2030 | | − } else if (t >= 'a') { |
| 2031 | + else if (t >= 'a') |
| 2031 | 2032 | t = t - 'a' + 10; |
| 2032 | | − } else if (t >= 'A') { |
| 2033 | + else if (t >= 'A') |
| 2033 | 2034 | t = t - 'A' + 10; |
| 2034 | | − } else { |
| 2035 | + else |
| 2035 | 2036 | t = t - '0'; |
| 2036 | | − if (t >= b) |
| 2037 | | − tcc_error("invalid digit"); |
| 2038 | | − } |
| 2037 | + if (t >= b) |
| 2038 | + tcc_error("invalid digit"); |
| 2039 | 2039 | n1 = n; |
| 2040 | 2040 | n = n * b + t; |
| 2041 | 2041 | /* detect overflow */ |
| @@ -2043,50 +2043,57 @@ static void parse_number(const char *p) · 1 unmodified line |
| 2043 | 2043 | if (n < n1) |
| 2044 | 2044 | tcc_error("integer constant overflow"); |
| 2045 | 2045 | } |
| 2046 | | − |
| 2047 | | − /* XXX: not exactly ANSI compliant */ |
| 2048 | | − if ((n & 0xffffffff00000000LL) != 0) { |
| 2049 | | − if ((n >> 63) != 0) |
| 2050 | | − tok = TOK_CULLONG; |
| 2051 | | − else |
| 2052 | | − tok = TOK_CLLONG; |
| 2053 | | − } else if (n > 0x7fffffff) { |
| 2054 | | − tok = TOK_CUINT; |
| 2055 | | − } else { |
| 2056 | | − tok = TOK_CINT; |
| 2057 | | − } |
| 2058 | | − lcount = 0; |
| 2059 | | − ucount = 0; |
| 2046 | + |
| 2047 | + /* Determine the characteristics (unsigned and/or 64bit) the type of |
| 2048 | + the constant must have according to the constant suffix(es) */ |
| 2049 | + lcount = ucount = must_64bit = 0; |
| 2050 | + p1 = p; |
| 2060 | 2051 | for(;;) { |
| 2061 | 2052 | t = toup(ch); |
| 2062 | 2053 | if (t == 'L') { |
| 2063 | 2054 | if (lcount >= 2) |
| 2064 | 2055 | tcc_error("three 'l's in integer constant"); |
| 2056 | + if (lcount && *(p - 1) != ch) |
| 2057 | + tcc_error("incorrect integer suffix: %s", p1); |
| 2065 | 2058 | lcount++; |
| 2066 | 2059 | #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE |
| 2067 | | − if (lcount == 2) { |
| 2068 | | −#endif |
| 2069 | | − if (tok == TOK_CINT) |
| 2070 | | − tok = TOK_CLLONG; |
| 2071 | | − else if (tok == TOK_CUINT) |
| 2072 | | − tok = TOK_CULLONG; |
| 2073 | | −#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE |
| 2074 | | − } |
| 2060 | + if (lcount == 2) |
| 2075 | 2061 | #endif |
| 2062 | + must_64bit = 1; |
| 2076 | 2063 | ch = *p++; |
| 2077 | 2064 | } else if (t == 'U') { |
| 2078 | 2065 | if (ucount >= 1) |
| 2079 | 2066 | tcc_error("two 'u's in integer constant"); |
| 2080 | 2067 | ucount++; |
| 2081 | | − if (tok == TOK_CINT) |
| 2082 | | − tok = TOK_CUINT; |
| 2083 | | − else if (tok == TOK_CLLONG) |
| 2084 | | − tok = TOK_CULLONG; |
| 2085 | 2068 | ch = *p++; |
| 2086 | 2069 | } else { |
| 2087 | 2070 | break; |
| 2088 | 2071 | } |
| 2089 | 2072 | } |
| 2073 | + |
| 2074 | + /* Whether 64 bits are needed to hold the constant's value */ |
| 2075 | + if (n & 0xffffffff00000000LL || must_64bit) { |
| 2076 | + tok = TOK_CLLONG; |
| 2077 | + n1 = n >> 32; |
| 2078 | + } else { |
| 2079 | + tok = TOK_CINT; |
| 2080 | + n1 = n; |
| 2081 | + } |
| 2082 | + |
| 2083 | + /* Whether type must be unsigned to hold the constant's value */ |
| 2084 | + if (ucount || ((n1 >> 31) && (b != 10))) { |
| 2085 | + if (tok == TOK_CLLONG) |
| 2086 | + tok = TOK_CULLONG; |
| 2087 | + else |
| 2088 | + tok = TOK_CUINT; |
| 2089 | + /* If decimal and no unsigned suffix, bump to 64 bits or throw error */ |
| 2090 | + } else if (n1 >> 31) { |
| 2091 | + if (tok == TOK_CINT) |
| 2092 | + tok = TOK_CLLONG; |
| 2093 | + else |
| 2094 | + tcc_error("integer constant overflow"); |
| 2095 | + } |
| 2096 | + |
| 2090 | 2097 | if (tok == TOK_CINT || tok == TOK_CUINT) |
| 2091 | 2098 | tokc.ui = n; |
| 2092 | 2099 | else |