|
From: <sv...@va...> - 2007-12-09 02:14:35
|
Author: sewardj
Date: 2007-12-09 02:14:35 +0000 (Sun, 09 Dec 2007)
New Revision: 7284
Log:
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.
Modified:
trunk/helgrind/hg_wordfm.c
Modified: trunk/helgrind/hg_wordfm.c
===================================================================
--- trunk/helgrind/hg_wordfm.c 2007-12-09 02:08:42 UTC (rev 7283)
+++ trunk/helgrind/hg_wordfm.c 2007-12-09 02:14:35 UTC (rev 7284)
@@ -142,6 +142,15 @@
+ (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 @@
}
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 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 @@
{
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];
}
|