I've discussed the below with otto@, who thought it was sound but wanted confirmation before I commit.
While debugging rarpd(8) for unrelated reasons, I noticed a loop of the following form: > for (i = 1; i; i <<= 1) where i is an int. This relies on shifting into and then out of the sign bit, both of which are undefined operations. The loop contains no breaks or returns, so they are always executed. It was copied around a few times, so there are a few nearly identical instances included in the below diff. These instances use i for: o boolean tests o comparison with small positive constants (RTA_*) o &ing with an int The third case seems questionable. However, (IIUC) integer conversion rules dictate that the int is implicitly cast to an unsigned int[1] and that two's complement arithmetic is preserved in this cast.[2] C integer type rules are such a joy to work with... Am I interpreting this correctly? [1] Usual Arithmetic Conversions #3 in: https://www.securecoding.cert.org/confluence/x/QgE [2] C99/C11 6.3.1.3 http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf Index: sbin/dhclient/dhclient.c =================================================================== RCS file: /cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.370 diff -u -p -r1.370 dhclient.c --- sbin/dhclient/dhclient.c 12 Dec 2015 14:48:17 -0000 1.370 +++ sbin/dhclient/dhclient.c 21 Jan 2016 02:16:17 -0000 @@ -160,7 +160,7 @@ int findproto(char *cp, int n) { struct sockaddr *sa; - int i; + unsigned int i; if (n == 0) return -1; Index: usr.sbin/arp/arp.c =================================================================== RCS file: /cvs/src/usr.sbin/arp/arp.c,v retrieving revision 1.70 diff -u -p -r1.70 arp.c --- usr.sbin/arp/arp.c 8 Dec 2015 14:20:24 -0000 1.70 +++ usr.sbin/arp/arp.c 21 Jan 2016 02:16:17 -0000 @@ -695,7 +695,7 @@ rtget(struct sockaddr_inarp **sinp, stru struct sockaddr_dl *sdl = NULL; struct sockaddr *sa; char *cp; - int i; + unsigned int i; if (rtmsg(RTM_GET) < 0) return (1); Index: usr.sbin/ndp/ndp.c =================================================================== RCS file: /cvs/src/usr.sbin/ndp/ndp.c,v retrieving revision 1.68 diff -u -p -r1.68 ndp.c --- usr.sbin/ndp/ndp.c 12 Jan 2016 09:47:13 -0000 1.68 +++ usr.sbin/ndp/ndp.c 21 Jan 2016 02:16:17 -0000 @@ -879,7 +879,7 @@ rtget(struct sockaddr_in6 **sinp, struct struct sockaddr_dl *sdl = NULL; struct sockaddr *sa; char *cp; - int i; + unsigned int i; if (rtmsg(RTM_GET) < 0) return (1); Index: usr.sbin/rarpd/arptab.c =================================================================== RCS file: /cvs/src/usr.sbin/rarpd/arptab.c,v retrieving revision 1.25 diff -u -p -r1.25 arptab.c --- usr.sbin/rarpd/arptab.c 19 Nov 2015 19:31:20 -0000 1.25 +++ usr.sbin/rarpd/arptab.c 21 Jan 2016 02:16:17 -0000 @@ -240,7 +240,7 @@ rtget(struct sockaddr_inarp **sinp, stru struct sockaddr_dl *sdl = NULL; struct sockaddr *sa; char *cp; - int i; + unsigned int i; if (rtmsg(RTM_GET) < 0) return (1);