Closed Bug 21428 Opened 25 years ago Closed 25 years ago

LL_CMP(foo, <=, bar) is broken when !HAVE_LONG_LONG

Categories

(NSPR :: NSPR, defect, P3)

All
Mac System 8.5
defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: sfraser_bugs, Assigned: wtc)

References

Details

The LL_CMP macro looks like this when HAVE_LONG_LONG is not defined:

#define LL_CMP(a, op, b)    (((PRInt32)(a).hi op (PRInt32)(b).hi) || \
                 (((a).hi == (b).hi) && ((a).lo op (b).lo)))

This fails if |op| is |<=| or |>=|, because the comparison is short-circuited at
the first a.hi |op| b.hi comparison.

This bug required workarounds noted in bug 21189, and will affect a number of
other places in the codebase where LL_CMP is used with <= or >= (e.g. IMAP code)
cc: brendan, who apparently wrote the macro, and used to have a big comment
saying that it was a no-no to use it with operators that tested for equality.
That comment seems to have gone.
Note that pr/src/md/unix/unix.c contains an illegal use of the LL_CMP macro (line
2671)
Status: NEW → ASSIGNED
How about this?

#define LL_CMP(a, op, b) \
    ((((a).hi != (b).hi) && ((PRInt32)(a).hi op (PRInt32)(b).hi)) || \
    (((a).hi == (b).hi) && ((a).lo op (b).lo)))

This should allow LL_CMP to be used with <, >, <=, and >=.
No need to fix the comments, documentation, and the existing
illegal uses of LL_CMP.
Depends on: 21473
How about:

#define LL_CMP(a, op, b) \
	(((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
	((PRInt32)(a).hi op (PRInt32)(b).hi))

John, your solution is right on.  Thanks.

The unsigned version of the macro needs to be fixed
similarly:

#define LL_UCMP(a, op, b) \
        (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
        ((a).hi op (b).hi))
Blocks: 21472
I checked in the fix for the LL_CMP and LL_UCMP
macros on the NSPRPUB_RELEASE_4_0_BRANCH.
/cvsroot/mozilla/nsprpub/pr/include/prlong.h, revision 3.6.4.1
No longer blocks: 21472
It turns out that with this change, all the comparison
operators (<, >, <=, >=, ==, and !=) can be used with
the LL_CMP or LL_UCMP macro.
The fix is checked into the main trunk.
/cvsroot/mozilla/nsprpub/pr/include/prlong.h, revision 3.7
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Blocks: 21472
No longer depends on: 21473
Blocks: 21473
I added test cases to reproduce the LL_CMP(foo, <=, bar) bug.
/cvsroot/mozilla/nsprpub/pr/tests/lltest.c, revision 3.2.58.1
You need to log in before you can comment on or make changes to this bug.