]> git.ipfire.org Git - location/libloc.git/commitdiff
address: Never pass zero to __builtin_ctz
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 6 Mar 2025 17:59:03 +0000 (17:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 6 Mar 2025 17:59:03 +0000 (17:59 +0000)
This is undefined behaviour which worked just fine in GCC, but in clang
the code is doing funny business.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libloc/address.h

index 082c33f42c10c507feb418e14acd1937ff68331f..ff6e9434f44eb8db9254ebd38032f18e05d5e4fb 100644 (file)
@@ -132,6 +132,7 @@ static inline struct in6_addr loc_prefix_to_bitmask(const unsigned int prefix) {
 
 static inline unsigned int loc_address_bit_length(const struct in6_addr* address) {
        unsigned int bitlength = 0;
+       int trailing_zeroes;
 
        int octet = 0;
 
@@ -143,8 +144,14 @@ static inline unsigned int loc_address_bit_length(const struct in6_addr* address
 
        // Walk backwards until we find the first one
        foreach_octet_in_address_reverse(octet, address) {
+               // __builtin_ctz does not support zero as input
+               if (!address->s6_addr[octet]) {
+                       bitlength -= 8;
+                       continue;
+               }
+
                // Count all trailing zeroes
-               int trailing_zeroes = __builtin_ctz(address->s6_addr[octet]);
+               trailing_zeroes = __builtin_ctz(address->s6_addr[octet]);
 
                // We only have one byte
                if (trailing_zeroes > 8)