summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-08-26 11:52:55 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-08-26 11:52:55 +0000
commitff06305f945015c7a33b8f694168714c75e7bf84 (patch)
treef0df13e6e4fec79ea688cb1480647415846882e2
parentdb32f795618df356c386aedf757d1d21055d96f9 (diff)
Evaluate arguments of bitstring macros only once.
According to bit_alloc(3) man page the arguments to bitstring macros are evaluated only once and may safely have side effects. Fix the implementation with temporary variables to fulfill this requirement. OK florian@ deraadt@
-rw-r--r--include/bitstring.h20
1 files changed, 13 insertions, 7 deletions
diff --git a/include/bitstring.h b/include/bitstring.h
index 13528746800..406a973581e 100644
--- a/include/bitstring.h
+++ b/include/bitstring.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bitstring.h,v 1.6 2020/05/10 00:56:06 guenther Exp $ */
+/* $OpenBSD: bitstring.h,v 1.7 2024/08/26 11:52:54 bluhm Exp $ */
/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */
/*
@@ -70,16 +70,22 @@ typedef unsigned char bitstr_t;
((name)[bitstr_size(nbits)])
/* is bit N of bitstring name set? */
-#define bit_test(name, bit) \
- ((name)[_bit_byte(bit)] & _bit_mask(bit))
+#define bit_test(name, bit) ({ \
+ register int __tbit = (bit); \
+ ((name)[_bit_byte(__tbit)] & _bit_mask(__tbit)); \
+})
/* set bit N of bitstring name */
-#define bit_set(name, bit) \
- ((name)[_bit_byte(bit)] |= _bit_mask(bit))
+#define bit_set(name, bit) do { \
+ register int __sbit = (bit); \
+ ((name)[_bit_byte(__sbit)] |= _bit_mask(__sbit)); \
+} while(0)
/* clear bit N of bitstring name */
-#define bit_clear(name, bit) \
- ((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
+#define bit_clear(name, bit) do { \
+ register int __cbit = (bit); \
+ ((name)[_bit_byte(__cbit)] &= ~_bit_mask(__cbit)); \
+} while(0)
/* clear bits start ... stop in bitstring */
#define bit_nclear(name, start, stop) do { \