On Mon, May 8, 2017 at 1:23 PM, Christian Brabandt <[email protected]> wrote: > > On Mo, 08 Mai 2017, R0b0t1 wrote: > >> On Sat, May 6, 2017 at 8:45 PM, James McCoy <[email protected]> wrote: >> > On Fri, May 05, 2017 at 10:23:49PM +0200, Bram Moolenaar wrote: >> >> James McCoy wrote: >> >> > It would be nice for there to be defined behavior here for the user, >> >> > instead of exposing them to the whims of the compiler implementation. >> >> >> >> Unfortunately, that is quite difficult. I propose the compiler standard >> >> gets fixed. This means only the few compilers that exist need to take >> >> care of this, instead of the millions of C programs. >> > >> > Since that's unlikely to happen, how about fixing it in one editor >> > instead of passing it off to all the Vim users? >> > >> >> I'm willing to help implement it. Unfortunately, the most >> straightforward solution, using `-ftrapv` and catching the resulting >> SIGABRT when overflow occurs, suffers from a bug in GCC dating from >> '08: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=35412. `-ftrapv` >> does seem to work in the current release of Cygwin, but did not work >> last I tried it on Linux. >> >> A possible workaround is the combination of `-fsanitize=undefined`, >> `-fsanitize=signed-integer-overflow`, and >> `-fsanitize-undefined-trap-on-error`. The last flag given does not >> seem to be documented. When it is used to compile a test program under >> Cygwin and that program executed I receive an illegal instruction core >> dump. I have yet to test it on a GNU/Linux toolchain. >> >> ``` >> #include <signal.h> >> #include <stdio.h> >> #include <limits.h> >> >> void >> handler(int signum) >> { >> printf("Overflow detected.\n"); >> } >> >> int >> main(int argc, char *argv[]) >> { >> int i = INT_MAX; >> signal(SIGABRT, &handler); >> i++; >> >> return 0; >> } >> ``` >> >> `gcc -ftrapv` >> `gcc --fsanitize=undefined -fsanitize=signed-integer-overflow >> -fsanitize-undefined-trap-on-error` > > So what would you suggest to implement a sane behaviour? >
That depends. The OP's title merely references defining the behavior. Vimscript could be defined to have wrapping arithmetic operations and this discussion would then be over. The other option, which seems like it is more in the spirit of the body of the original post, and which eliminates the word "undefined" per the C standard, involves trapping integer overflow and underflow or ensuring overflow or underflow never occurs. This can be done in the following ways: 1) For some POSIX systems using GCC, it might be necessary to wait until the bug with "-ftrapv" is fixed and and the patch distributed. 2) For some POSIX systems using GCC nothing needs to be done and "-ftrapv" is usable. 3) For all(?) POSIX systems the combination of "-fsanitize=undefined -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error" works despite "-ftrapv" not working. 4) For Windows it is possible to generate an SEH exception on overflow or underflow, however I'm not sure what other facilities expose this functionality. 5) For all supported systems explicit range checks could be done for vimscript arithmetic. 6) For all supported systems a large number library could be used to eliminate the possibility of overflow or underflow. With respect to the combination of 1, 2, and 3, some reading on the issue (http://blog.robertelder.org/gcc-signed-overflow-trapping-ftrapv-doesnt-work/) implies that newer versions of GCC might not suffer from the "-ftrapv" problem. It may be a better idea to use the flags given in item 3 anyway, as they seem to be newer; unfortunately that generates SIGILL instead of SIGABRT and I can't find a way to recover from that signal in a portable way. My only comment on 4 is that some programs are unable to use SEH, and vim is likely among them, but someone else would have to comment. 5 and 6 are likely the most work, but also provide the most flexibility. 6 might eventually be a goal anyway, but I'm not aware of anyone having problems with the range of the datatypes in vimscript. That still leaves the question of what happens when overflow or underflow occurs. If overflow and underflow are disallowed, clamping the value and continuing execution is the only choice I'm aware of that doesn't involve throwing an exception or halting execution - not that those are unreasonable choices. As to implementation, the first three (or four) items would require creating the signal handler and exposing the vimscript interpreter internals to it. Comments on the best way to do that are very welcome, I'm not too familiar with the Vim codebase. Five would simply involve adding the range checks manually and reporting an error (or clamping the values) when exceptional arithmetic occurs. Or, *instead of all of the above,* arithmetic can be defined to wrap. Technically, with no other changes, this doesn't solve the original complaint about undefined behavior - as it is left undefined in the C standard, Vim could conceivably be ported to a system which does wrap exceptional arithmetic by default. -- -- 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.
