]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Don't do comparisons of (signed) Words by merely subtracting them, as
authorJulian Seward <jseward@acm.org>
Sun, 9 Dec 2007 02:14:35 +0000 (02:14 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 9 Dec 2007 02:14:35 +0000 (02:14 +0000)
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

helgrind/hg_wordfm.c

index faaeec740f0648da5a606e7153d011fdb2ab5511..d6183c947ae5610ce91e84badf204504a75a7daa 100644 (file)
@@ -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];
       }