Skip to content

Commit 79228be

Browse files
committed
acl_hash: fix integer conversion warning
Avoid integer conversion altogether by using a more efficient implementation which compiles to branchless code with a rotate instruction, assuming the number of bits to rotate by is known at compile time so the compiler may eliminate the assert(). Signed-off-by: Peter Colberg <[email protected]>
1 parent aab7793 commit 79228be

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

lib/acl_hash/src/acl_hash.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,25 @@ static void l_close(acl_hash_sha1_context_t *c, char *digest_buf) {
213213
digest_buf[40] = 0;
214214
}
215215

216-
static uint32_t l_leftrotate(uint32_t v, unsigned bits) {
217-
uint64_t both = ((uint64_t)v) << bits;
218-
uint32_t hi = both >> 32;
219-
uint32_t lo = both & 0xffffffff;
220-
return hi | lo;
216+
#ifdef _MSC_VER
217+
#pragma warning(push)
218+
// The MSVC /sdl flag turns this false-positive warning into an error:
219+
// C4146: unary minus operator applied to unsigned type, result still unsigned
220+
// https://developercommunity.visualstudio.com/t/c4146-unary-minus-operator-applied-to-unsigned-typ/884520
221+
#pragma warning(disable : 4146)
222+
#endif
223+
224+
// See Safe, Efficient, and Portable Rotate in C/C++ by John Regehr.
225+
// https://blog.regehr.org/archives/1063
226+
static uint32_t l_leftrotate(uint32_t v, uint32_t bits) {
227+
assert(bits < 32);
228+
return (v << bits) | (v >> ((-bits) & 31));
221229
}
222230

231+
#ifdef _MSC_VER
232+
#pragma warning(pop)
233+
#endif
234+
223235
static uint32_t l_read_bigendian_i32(const unsigned char *buf) {
224236
// Need to cast to uchar so we don't sign extend when widening out to 32 bits.
225237
uint32_t byte3 = buf[0];

0 commit comments

Comments
 (0)