Work around spurious compiler warning in inet operators
authorAndres Freund
Thu, 16 Mar 2023 21:08:44 +0000 (14:08 -0700)
committerAndres Freund
Thu, 16 Mar 2023 21:48:45 +0000 (14:48 -0700)
gcc 12+ has complaints like the following:

../../../../../pgsql/src/backend/utils/adt/network.c: In function 'inetnot':
../../../../../pgsql/src/backend/utils/adt/network.c:1893:34: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
 1893 |                         pdst[nb] = ~pip[nb];
      |                         ~~~~~~~~~^~~~~~~~~~
../../../../../pgsql/src/include/utils/inet.h:27:23: note: at offset -1 into destination object 'ipaddr' of size 16
   27 |         unsigned char ipaddr[16];       /* up to 128 bits of address */
      |                       ^~~~~~
../../../../../pgsql/src/include/utils/inet.h:27:23: note: at offset -1 into destination object 'ipaddr' of size 16

This is due to a compiler bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104986

It has been a year since the bug has been reported without getting fixed. As
the warnings are verbose and use of gcc 12 is becoming more common, it seems
worth working around the bug. Particularly because a simple reformulation of
the loop condition fixes the issue and isn't any less readable.

Author: Tom Lane 
Author: Andres Freund 
Discussion: https://postgr.es/m/144536.1648326206@sss.pgh.pa.us
Backpatch: 11-

src/backend/utils/adt/network.c

index ea1c7390d0d9017045bbe5f5f0ec29fe5d8287fe..ae11de0ba5007e445017b91acfeff3adc2e3d6af 100644 (file)
@@ -1874,7 +1874,7 @@ inetnot(PG_FUNCTION_ARGS)
        unsigned char *pip = ip_addr(ip);
        unsigned char *pdst = ip_addr(dst);
 
-       while (nb-- > 0)
+       while (--nb >= 0)
            pdst[nb] = ~pip[nb];
    }
    ip_bits(dst) = ip_bits(ip);
@@ -1906,7 +1906,7 @@ inetand(PG_FUNCTION_ARGS)
        unsigned char *pip2 = ip_addr(ip2);
        unsigned char *pdst = ip_addr(dst);
 
-       while (nb-- > 0)
+       while (--nb >= 0)
            pdst[nb] = pip[nb] & pip2[nb];
    }
    ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
@@ -1938,7 +1938,7 @@ inetor(PG_FUNCTION_ARGS)
        unsigned char *pip2 = ip_addr(ip2);
        unsigned char *pdst = ip_addr(dst);
 
-       while (nb-- > 0)
+       while (--nb >= 0)
            pdst[nb] = pip[nb] | pip2[nb];
    }
    ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
@@ -1963,7 +1963,7 @@ internal_inetpl(inet *ip, int64 addend)
        unsigned char *pdst = ip_addr(dst);
        int         carry = 0;
 
-       while (nb-- > 0)
+       while (--nb >= 0)
        {
            carry = pip[nb] + (int) (addend & 0xFF) + carry;
            pdst[nb] = (unsigned char) (carry & 0xFF);
@@ -2047,7 +2047,7 @@ inetmi(PG_FUNCTION_ARGS)
        unsigned char *pip2 = ip_addr(ip2);
        int         carry = 1;
 
-       while (nb-- > 0)
+       while (--nb >= 0)
        {
            int         lobyte;