Skip to content

Commit

Permalink
bswap.h: squelch potential sparse -Wcast-truncate warnings
Browse files Browse the repository at this point in the history
In put_be32(), we right-shift a uint32_t value various amounts and then
assign the low 8-bits to individual "unsigned char" bytes, throwing away
the high bits. For shifts smaller than 24 bits, those thrown away bits
will be arbitrary bits from the original uint32_t.

This works exactly as we want, but if you feed a constant, then sparse
complains. For example if we write this (which we plan to do in a future
patch):

  put_be32(hdr, PACK_SIGNATURE);

then "make sparse" produces:

  compat/bswap.h:175:22: error: cast truncates bits from constant value (5041 becomes 41)
  compat/bswap.h:176:22: error: cast truncates bits from constant value (504143 becomes 43)
  compat/bswap.h:177:22: error: cast truncates bits from constant value (5041434b becomes 4b)

And the same issue exists in the other put_be*() functions, when used
with a constant.

We can silence this warning by explicitly masking off the truncated
bits. The compiler is smart enough to know the result is the same, and
the asm generated by gcc (with both -O0 and -O2) is identical.

Curiously this line already exists:

	put_be32(&hdr_version, INDEX_EXTENSION_VERSION2);

in the fsmonitor.c file, but it does not get flagged because the CPP
macro expands to a small integer (2).

Signed-off-by: Jeff King <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
  • Loading branch information
gitster authored and dscho committed Feb 6, 2025
1 parent acb15be commit 6b442e6
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions compat/bswap.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,23 @@ static inline uint64_t get_be64(const void *ptr)
static inline void put_be32(void *ptr, uint32_t value)
{
unsigned char *p = ptr;
p[0] = value >> 24;
p[1] = value >> 16;
p[2] = value >> 8;
p[3] = value >> 0;
p[0] = (value >> 24) & 0xff;
p[1] = (value >> 16) & 0xff;
p[2] = (value >> 8) & 0xff;
p[3] = (value >> 0) & 0xff;
}

static inline void put_be64(void *ptr, uint64_t value)
{
unsigned char *p = ptr;
p[0] = value >> 56;
p[1] = value >> 48;
p[2] = value >> 40;
p[3] = value >> 32;
p[4] = value >> 24;
p[5] = value >> 16;
p[6] = value >> 8;
p[7] = value >> 0;
p[0] = (value >> 56) & 0xff;
p[1] = (value >> 48) & 0xff;
p[2] = (value >> 40) & 0xff;
p[3] = (value >> 32) & 0xff;
p[4] = (value >> 24) & 0xff;
p[5] = (value >> 16) & 0xff;
p[6] = (value >> 8) & 0xff;
p[7] = (value >> 0) & 0xff;
}

#endif /* COMPAT_BSWAP_H */

0 comments on commit 6b442e6

Please sign in to comment.