diff options
author | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-17 09:31:54 +0100 |
---|---|---|
committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-18 21:57:49 +0100 |
commit | ece19651c60c34e2fa5bed623dff82b9af4d8e11 (patch) | |
tree | c423f04ba00af46a3c38012becf557e83f211bff | |
parent | be90cdf4f9891ebd6cdf6b2ec6c34f3bcf465643 (diff) | |
download | rneovim-ece19651c60c34e2fa5bed623dff82b9af4d8e11.tar.gz rneovim-ece19651c60c34e2fa5bed623dff82b9af4d8e11.tar.bz2 rneovim-ece19651c60c34e2fa5bed623dff82b9af4d8e11.zip |
Fix warnings: eval.c: item_compare(): Garbage value: MI.
Problem : Result of operation is garbage or undefined @ 13565.
Diagnostic : Multithreading issue.
Rationale : Problem occurs only if global (static) variable
`item_compare_keep_zero` changes after being used by
`do_sort_uniq` but before being used by `item_compare` or
`item_compare2`.
Resolution : This is not an intra-function problem, as other MI's
before, but rather an inter-function one. Thus, it can't be
solved by using local copy of global. Therefore, we are
forced to do a bit refactoring. We can't simply add a bool
param to item_compare/item_compare2, as they couldn't be
passed to qsort() that way. So, item_compare/item_compare2
are added a bool param and curried versions of them are
added and used in their place.
-rw-r--r-- | src/nvim/eval.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9acde49105..44ea2b2332 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13545,13 +13545,12 @@ static bool item_compare_numeric; static char_u *item_compare_func; static dict_T *item_compare_selfdict; static int item_compare_func_err; -static bool item_compare_keep_zero; #define ITEM_COMPARE_FAIL 999 /* * Compare functions for f_sort() and f_uniq() below. */ -static int item_compare(const void *s1, const void *s2) +static int item_compare(const void *s1, const void *s2, bool keep_zero) { sortItem_T *si1, *si2; char_u *p1, *p2; @@ -13604,7 +13603,7 @@ static int item_compare(const void *s1, const void *s2) // When the result would be zero, compare the item indexes. Makes the // sort stable. - if (res == 0 && !item_compare_keep_zero) { + if (res == 0 && !keep_zero) { res = si1->idx > si2->idx ? 1 : -1; } @@ -13613,7 +13612,17 @@ static int item_compare(const void *s1, const void *s2) return res; } -static int item_compare2(const void *s1, const void *s2) +static int item_compare_keeping_zero(const void *s1, const void *s2) +{ + return item_compare(s1, s2, true); +} + +static int item_compare_not_keeping_zero(const void *s1, const void *s2) +{ + return item_compare(s1, s2, false); +} + +static int item_compare2(const void *s1, const void *s2, bool keep_zero) { sortItem_T *si1, *si2; int res; @@ -13650,13 +13659,23 @@ static int item_compare2(const void *s1, const void *s2) // When the result would be zero, compare the pointers themselves. Makes // the sort stable. - if (res == 0 && !item_compare_keep_zero) { + if (res == 0 && !keep_zero) { res = si1->idx > si2->idx ? 1 : -1; } return res; } +static int item_compare2_keeping_zero(const void *s1, const void *s2) +{ + return item_compare2(s1, s2, true); +} + +static int item_compare2_not_keeping_zero(const void *s1, const void *s2) +{ + return item_compare2(s1, s2, false); +} + /* * "sort({list})" function */ @@ -13737,15 +13756,16 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } item_compare_func_err = FALSE; - item_compare_keep_zero = false; // Test the compare function. if (item_compare_func != NULL - && item_compare2(&ptrs[0], &ptrs[1]) == ITEM_COMPARE_FAIL) { + && item_compare2_not_keeping_zero(&ptrs[0], &ptrs[1]) + == ITEM_COMPARE_FAIL) { EMSG(_("E702: Sort compare function failed")); } else { // Sort the array with item pointers. qsort(ptrs, (size_t)len, sizeof (sortItem_T), - item_compare_func == NULL ? item_compare : item_compare2); + item_compare_func == NULL ? item_compare_not_keeping_zero : + item_compare2_not_keeping_zero); if (!item_compare_func_err) { // Clear the list and append the items in the sorted order. @@ -13764,8 +13784,8 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) // f_uniq(): ptrs will be a stack of items to remove. item_compare_func_err = FALSE; - item_compare_keep_zero = true; - item_compare_func_ptr = item_compare_func ? item_compare2 : item_compare; + item_compare_func_ptr = item_compare_func ? item_compare2_keeping_zero : + item_compare_keeping_zero; for (li = l->lv_first; li != NULL && li->li_next != NULL; li = li->li_next) { if (item_compare_func_ptr(&li, &li->li_next) == 0) { |