Skip to content

Commit d7a7f40

Browse files
Fix asserting arithmetic on big-endian platforms (#2092)
This fixes a latent issue on big-endian platforms that was exposed by the merge of PR#2074, which does an `mlib_assert_mul(int32_t, ...)`. Broken: If the target type of a ckdint-asserting-arithmetic macro is smaller than `intmax_t`, then the return value of the function will be bogus on big-endian platforms, because we neglected to adjust the temporary bits used to store the result. Fix: If the platform is big-endian, we bit-shift the temporary result down by the number of bytes of different between `uintmax_t` and the destination type size.
1 parent 923c267 commit d7a7f40

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

src/common/src/mlib/ckdint.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,13 @@ static inline uintmax_t(_mlib_assert_ckdint)(size_t dst_sz,
629629
b_str);
630630
abort();
631631
}
632+
if (!mlib_is_little_endian()) {
633+
// We unconditionally set the leading bytes of `tmp`, but big-endian expects
634+
// the lower place values to be in the later bytes. If the target int is
635+
// smaller than intmax, we must shift all the bits over to their proper
636+
// position. This expression is trivially constant-folded by an optimizer.
637+
tmp >>= ((size_t)CHAR_BIT * ((sizeof tmp) - dst_sz));
638+
}
632639
return tmp;
633640
}
634641

src/common/tests/test-mlib.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,13 @@ _test_ckdint_partial(void)
768768
mlib_check(mlib_mul(&a, 3, INTMAX_MAX));
769769
mlib_check(a, eq, INTMAX_MAX - 2);
770770
}
771+
772+
{
773+
// Check asserting form with a dest type smaller than intmax, which triggers
774+
// a special branch on big-endian systems.
775+
int32_t const i = mlib_assert_mul(int32_t, -908, 1000);
776+
mlib_check(i, eq, -908000);
777+
}
771778
}
772779

773780
static void

0 commit comments

Comments
 (0)