Hi,

On Fri, Dec 16, 2016 at 2:51 AM, Mike Williams
<[email protected]> wrote:
>
>>>>
>>>> Yegappan Lakshmanan wrote:
>>>>>
>>>>> eval.c:4432:10: runtime error: negation of -9223372036854775808 cannot
>>>>> be represented in type 'varnumber_T' (aka 'long long'); cast to an
>>>>> unsigned type to negate this value to itself
>>>>
>>>>
>>>> I see it too.
>>>> It's coming from this line in Test_num64() in test_viml.vim:
>>>>
>>>> call assert_equal(-9223372036854775808,  0 / 0)
>>>>
>>>> Running  :echo -9223372036854775808
>>>> also gives the ubsan error.
>>>>
>>>> viml parser is considering the number 9223372036854775808
>>>> (which is not a valid long long) and then negating it, instead
>>>> of considering it as number -9223372036854775808
>>>> (which is a valid long long). Not sure how it can be fix.
>>>> Even though it's undefined behavior, it probably works
>>>> on all platforms in practice.  The test would probably
>>>> fail if it did not work. But it would be good to avoid undefined
>>>> behavior.
>>>
>>>
>>> The usual idiom for writing an integer constant for the largest negative
>>> value 2s complement integer is to negate the largest positive value and
>>> subtract 1.  So use (-9223372036854775807 - 1)?
>>
>>
>> Apologies.  That just solves the issue with the test and not the
>> underlying problem.  Caffeine took too long to kick in.
>>
>> The cause is a combination of things.  eval7() parses integers as
>> unsigned values but uses the signed value returned from vim_str2nr()
>> before applying any unary minus.  In turn vim_str2nr() casts the
>> unsigned value of the integer to a signed value, so the value it returns
>> depends on whether the top bit is set from the unsigned calculation.
>> (Casting is lying to the compiler who will have its revenge one day -
>> looks like today is that day ;))
>>
>> VIM doesn't signal (AFAIK) out of range integer values.  At the moment,
>> with the wrapping unsigned integer math in vim_str2nr(), the result for
>> large integers is unpredictable (for those not concerned with integer
>> representation)  Applying a saturating calculation would at least return
>> results as close as possible to the original integer value maintaining
>> sign.
>>
>> So the simplest change would be to have vim_str2nr() saturate and return
>> 9223372036854775807 as the largest positive varnumber_T supported.
>> eval7() would then apply the unary minus and return -9223372036854775807
>>
>> You will still need to use -9223372036854775807 - 1 in the original test
>> to generate the largest negative integer value possible in VIM.
>
>
> Patch attached to limit range of parsed integer numbers, cope with 2s
> complement asymmetry, and modify test that was triggering the UB warning.
> Tests pass but I don't have clang to check the UB warning so please test for
> that.
>

I reran the tests with your patch (with UBSan) and the above runtime
error is resolved.

Only the following runtime errors are remaining:

eval.c:4068:15: runtime error: division by zero
channel.c:713:5: runtime error: load of misaligned address
0x60b0000069ca for type 'char *', which requires 8 byte alignment

- Yegappan

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui