From: Julian Seward Date: Sun, 9 Dec 2007 02:14:35 +0000 (+0000) Subject: Don't do comparisons of (signed) Words by merely subtracting them, as X-Git-Tag: svn/VALGRIND_3_3_0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=840f6f5b33cf1a852df31cfa97adcbcfc0c92015;p=thirdparty%2Fvalgrind.git Don't do comparisons of (signed) Words by merely subtracting them, as this does not always produce correct results. Instead use a slower but correct method. Analogous fix to that applied to m_oset.c by r7283. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7284 --- diff --git a/helgrind/hg_wordfm.c b/helgrind/hg_wordfm.c index faaeec740f..d6183c947a 100644 --- a/helgrind/hg_wordfm.c +++ b/helgrind/hg_wordfm.c @@ -142,6 +142,15 @@ static Word size_avl_nonNull ( AvlNode* nd ) + (nd->child[1] ? size_avl_nonNull(nd->child[1]) : 0); } +/* Signedly compare w1 and w2. If w1 < w2, produce a negative number; + if w1 > w2 produce a positive number, and if w1 == w2 produce + zero. */ +static inline Word cmp_signed_Words ( Word w1, Word w2 ) { + if (w1 < w2) return -1; + if (w1 > w2) return 1; + return 0; +} + /* Insert element a into the AVL tree t. Returns True if the depth of the tree has grown. If element with that key is already present, just copy a->val to existing node, first returning old ->val field @@ -169,7 +178,8 @@ Bool avl_insert_wrk ( AvlNode** rootp, } cmpres = kCmp ? /*boxed*/ kCmp( (*rootp)->key, a->key ) - : /*unboxed*/ ((Word)(*rootp)->key) - ((Word)a->key); + : /*unboxed*/ cmp_signed_Words( (Word)(*rootp)->key, + (Word)a->key ); if (cmpres > 0) { /* insert into the left subtree */ @@ -257,7 +267,8 @@ Bool avl_remove_wrk ( AvlNode** rootp, Bool ch; Word cmpres; cmpres = kCmp ? /*boxed*/ kCmp( (*rootp)->key, a->key ) - : /*unboxed*/ ((Word)(*rootp)->key) - ((Word)a->key); + : /*unboxed*/ cmp_signed_Words( (Word)(*rootp)->key, + (Word)a->key ); if (cmpres > 0){ /* remove from the left subtree */ @@ -382,23 +393,23 @@ AvlNode* avl_find_node ( AvlNode* t, Word k, Word(*kCmp)(Word,Word) ) { if (kCmp) { /* Boxed comparisons */ - Word cmpres; + Word cmpresS; while (True) { if (t == NULL) return NULL; - cmpres = kCmp(t->key, k); - if (cmpres > 0) t = t->child[0]; else - if (cmpres < 0) t = t->child[1]; else + cmpresS = kCmp(t->key, k); + if (cmpresS > 0) t = t->child[0]; else + if (cmpresS < 0) t = t->child[1]; else return t; } } else { /* Unboxed comparisons */ - Word cmpres; /* signed */ + Word cmpresS; /* signed */ UWord cmpresU; /* unsigned */ while (True) { if (t == NULL) return NULL; /* unlikely ==> predictable */ - cmpres = ((Word)t->key) - ((Word)k); - if (cmpres == 0) return t; /* unlikely ==> predictable */ - cmpresU = (UWord)cmpres; + cmpresS = cmp_signed_Words( (Word)t->key, (Word)k ); + if (cmpresS == 0) return t; /* unlikely ==> predictable */ + cmpresU = (UWord)cmpresS; cmpresU >>=/*unsigned*/ (8 * sizeof(cmpresU) - 1); t = t->child[cmpresU]; }