This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] sys/types.h: Avoid bit-manipulation of signed values


Sorry, let's try that again...

On Thu, 2015-11-12 at 15:11 +1100, Nick Withers wrote:
> Hi all,
> 
> The patch below attempts to resolve potential undefined behaviour in
> bit-manipulation in the FD_* macros, also clearing up the GCC warning
> "conversion to 'unsigned int' from 'int' may change the sign of the
> result" with -Wsign-conversion and an int FD parameter.
____

diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
index d8d6fdc..c7ed0ab 100644
--- a/newlib/libc/include/sys/types.h
+++ b/newlib/libc/include/sys/types.h
@@ -217,7 +217,7 @@ typedef unsigned short nlink_t;
 */
 # if !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (_WINSOCKAPI_) || defined (__USE_W32_SOCKETS)) 
 #  define _SYS_TYPES_FD_SET
-#  define	NBBY	8		/* number of bits in a byte */
+#  define	NBBY	8U		/* number of bits in a byte */
 /*
  * Select uses bit masks of file descriptors in longs.
  * These macros manipulate such bit fields (the filesystem macros use chars).
@@ -225,13 +225,13 @@ typedef unsigned short nlink_t;
  * should be >= NOFILE (param.h).
  */
 #  ifndef	FD_SETSIZE
-#	define	FD_SETSIZE	64
+#	define	FD_SETSIZE	64U
 #  endif
 
-typedef	long	fd_mask;
+typedef	unsigned long	fd_mask;
 #  define	NFDBITS	(sizeof (fd_mask) * NBBY)	/* bits per mask */
 #  ifndef	howmany
-#	define	howmany(x,y)	(((x)+((y)-1))/(y))
+#	define	howmany(x,y)	(((x)+((y)-1U))/(y))
 #  endif
 
 /* We use a macro for fd_set so that including Sockets.h afterwards
@@ -242,9 +242,9 @@ typedef	struct _types_fd_set {
 
 #define fd_set _types_fd_set
 
-#  define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
-#  define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
-#  define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
+#  define	FD_SET(n, p)	((p)->fds_bits[(unsigned int)(n)/NFDBITS] |= ((fd_mask) 1U << ((unsigned int) (n) % NFDBITS)))
+#  define	FD_CLR(n, p)	((p)->fds_bits[(unsigned int)(n)/NFDBITS] &= ~((fd_mask) 1U << ((unsigned int) (n) % NFDBITS)))
+#  define	FD_ISSET(n, p)	((p)->fds_bits[(unsigned int)(n)/NFDBITS] & ((fd_mask) 1U << ((unsigned int) (n) % NFDBITS)))
 #  define	FD_ZERO(p)	(__extension__ (void)({ \
      size_t __i; \
      char *__tmp = (char *)p; \
____

> If folk're happy with this, should I make similar changes to
> "newlib/libc/sys/linux/sys/types.h"? Not sure I want to touch
> "winsup/cygwin/include/sys/param.h"... :-P
> 
> Ta!


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]