aboutsummaryrefslogtreecommitdiff
path: root/test/unit/viml/expressions/parser_tests.lua
diff options
context:
space:
mode:
authorPhlosioneer <mattmdrr2@gmail.com>2017-11-19 19:55:28 -0500
committerJustin M. Keyes <justinkz@gmail.com>2017-11-20 01:55:28 +0100
commitdf107149913f82e8b3b6b2060d6dbed3d90e68fe (patch)
tree1a6e1cdc3a404b921d26279ffdd01399e00c7d3c /test/unit/viml/expressions/parser_tests.lua
parentde8b1fd1dee5a91b2893fccc53cfd11631ccba38 (diff)
downloadrneovim-df107149913f82e8b3b6b2060d6dbed3d90e68fe.tar.gz
rneovim-df107149913f82e8b3b6b2060d6dbed3d90e68fe.tar.bz2
rneovim-df107149913f82e8b3b6b2060d6dbed3d90e68fe.zip
server.c: Fix bug in release mode (#7594)
When compiling with CMAKE_BUILD_TYPE=RelWithDebInfo, several -Wmaybe-uninitialized warnings are printed. These were thought to be false positives (#5061); there are no control paths that lead to an uninitialized value. However, when gcc is run in -O2 mode, it makes a mistake while generating the necessary logic. Specifically, for the code: ... int = 0; // Index of the server whose address equals addr. for (; i < watchers.ga_len; i++) { watcher = ((SocketWatcher **)watchers.ga_data)[i]; // <snip> } if (i >= watchers.ga_len) { ELOG("Not listening on %s", addr); return; } ... Gcc generates: ... <+98>: cmp %ebx, %ebp <+100>: jg 0x530f13 <server_stop+55> <+102>: cmp %ebp, ebx <+104>: jl 0x530f7e <server_stop+162> ... Normally, the if statement should catch the only control path where watcher is not assigned: watchers.ga_len <= 0. When compiled, the assembly lines 98 and 100 correspond to checking if i < watchers.ga_len, and the lines 102 and 104 correspond to checking if i >= watchers.ga_len. The assembly seems to compare ebp (which is watchers.ga_len) with ebx (which is i), and jump if greater; then do the same comparison and jump if less. This is where gcc makes a mistake: it flips the order of the cmp instruction. This means that the REAL behavior is first check if i < watchers.ga_len and then check if i < watchers.ga_len. Which means the code inside the if statement is NEVER executed; no combination of i and watchers.ga_len will ever trigger ELOG(). So not only is this a use of an uninitialized value if watchers.ga_len == 0 (or technically, if it's less than zero too), it also clobbers any error detection if the for loop reaches the last entry (which would normally cause i == watchers.ga_len too). This commit fixes this issue by adding a bool to keep track of whether a watcher was found during the loop. This makes gcc generate the correct code, avoiding both bugs.
Diffstat (limited to 'test/unit/viml/expressions/parser_tests.lua')
0 files changed, 0 insertions, 0 deletions