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.
