[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] [BUG] [PATCH] v2, tcc and INT64: wrong result of comp
From: |
Sergey Korshunoff |
Subject: |
Re: [Tinycc-devel] [BUG] [PATCH] v2, tcc and INT64: wrong result of comparison (a test included) |
Date: |
Mon, 5 Jan 2015 22:17:29 +0300 |
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 <address@hidden>:
> 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 <address@hidden>:
>> 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 <address@hidden>:
>>> 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Tinycc-devel] [BUG] [PATCH] v2, tcc and INT64: wrong result of comparison (a test included),
Sergey Korshunoff <=