This is version 2 of the patch. A changed lines are
- if (is_signed && (-n == 0x80000000ULL))
+ if (is_signed && (n & 0x80000000ULL))
+ is_long_long = 1;
+
+ if (is_signed && (n & 0x8000000000000000ULL))
+ tcc_error("long long constant overflow");This is because a scanned constant is positive (a sign will be applied latter) If a sign bit is used by constant, then a bigger size is needed to store such constant. 2015-01-05 17:47 GMT+03:00, Sergey Korshunoff <[email protected]>: > tccpp(parse_number): changes to detect a constat type correctly. > This patch is tested with a nimrod compiler build process. All works. > > 2015-01-05 2:03 GMT+03:00, Sergey Korshunoff <[email protected]>: >> There is another approach: assume the constant is negative by default. >> This is the method used in nimrod to scan a constants: >> lib/pure/parseutils.nim(rawparse) >> >> proc rawParseInt(s: string, b: var BiggestInt, start: int = 0): int = >> var >> sign: BiggestInt = -1 # minus by defaul >> i = start >> if s[i] == '+': inc(i) >> elif s[i] == '-': >> inc(i) >> sign = 1 >> if s[i] in {'0'..'9'}: >> b = 0 >> while s[i] in {'0'..'9'}: >> b = b * 10 - (ord(s[i]) - ord('0')) #! the point >> inc(i) >> while s[i] == '_': inc(i) # underscores are allowed and ignored >> b = b * sign >> result = i - start >> >> >> Sun, 04 Jan 2015 16:51 +0000, Thomas Preud'homme <[email protected]>: >>> Le dimanche 4 janvier 2015, 19:18:34 Sergey Korshunoff a écrit : >>>> By replacing a -2147483648 with a -2147483647 I can succesfully build >>>> a working nim compiler. But this is not so good... >>> >>> The bug is in tccpp.c parse_number. The function tries to guess what >>> should >>> be >>> the size and sign of the litteral before parsing the suffix (which might >>> not >>> >>> exist). >>> >>> /* XXX: not exactly ANSI compliant */ >>> if ((n & 0xffffffff00000000LL) != 0) { >>> if ((n >> 63) != 0) >>> tok = TOK_CULLONG; >>> else >>> tok = TOK_CLLONG; >>> } else if (n > 0x7fffffff) { >>> tok = TOK_CUINT; >>> } else { >>> tok = TOK_CINT; >>> } >>> >>> In your case it will pass in the first else if and set tok to TOK_CUINT. >>> So >>> far >>> so good. >>> >>> Then it will parse the suffix and when it sees the second L it does >>> this: >>> >>> if (tok == TOK_CINT) >>> tok = TOK_CLLONG; >>> else if (tok == TOK_CUINT) >>> tok = TOK_CULLONG; >>> >>> So here it will set the value to TOK_CULLONG while it should set it to >>> TOK_CLLONG and warn if the value is too big. >>> >>> My feeling is that the automatic guess for the size and sign should be >>> done >>> >>> after trying to look for a suffix. >>> >>> The algorithm would be something like: >>> >>> 1) Set tok to TOK_CINT and suffix_found to false. >>> 2) Then look for a L or U suffix with unchanged code except for setting >>> a >>> suffix_found variable if any such suffix is found. >>> 3) Then if suffix_found is false try automatic detection, otherwise warn >>> of >>> >>> overflow and possibly process the overflow (what does GCC does in this >>> case?) Be >>> careful about the sign when checking for overflow. >>> >>> Do you want to take a stab at it? >>> >>> Best regards, >>> >>> Thomas >>> >> >
2015-01-05-3-tccpp-parse-number.patch
Description: Binary data
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
