Bruno and I get defect reports from Coverity Scan for Gnulib. The most recent one has this new complaint:

*** CID 1588680:  Incorrect expression  (ASSERT_SIDE_EFFECT)
/gltests/test-byteswap.c: 43 in test_bswap_eval_once()
37 38 /* Test that the bswap functions evaluate their arguments once. */
39     static void
40     test_bswap_eval_once (void)
41     {
42       uint_least16_t value_1 = 0;
>>>     CID 1588680:  Incorrect expression  (ASSERT_SIDE_EFFECT)
>>>     Argument "value_1++" of ASSERT() has a side effect.  The containing 
function might work differently in a non-debug build.
43       ASSERT (bswap_16 (value_1++) == 0);

I checked the glibc sources, and long ago glibc indeed had a bug in this area: bswap_16 and related function-like macros evaluated their arguments more than once. This bug was fixed in the following glibc commit dated Sat Aug 8 20:02:34 1998 +0000, and the fix appears in glibc 2.1 (1999).

https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=7ce241a03e2c0b49482d9d05c8ddb765e89a01d9


Gnulib does not support glibc 2.1.x and older, so this should not be a problem when porting to glibc. However, I worried that other platforms might have the bug, until I noticed that m4/byteswap.m4 already inadvertently tests for it. I installed the attached patch to document the test.

We can ignore this Coverity defect report as a false positive, just as we ignore many other defect reports.
From 6dbbada2b05bdc5efd0a5592a7805c92fe0531c6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 20 May 2024 09:08:27 -0700
Subject: [PATCH] * m4/byteswap.m4: Add comment about broken C libraries.

---
 m4/byteswap.m4 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/m4/byteswap.m4 b/m4/byteswap.m4
index 3f5ef45cfe..3185bab763 100644
--- a/m4/byteswap.m4
+++ b/m4/byteswap.m4
@@ -15,6 +15,10 @@ AC_DEFUN([gl_BYTESWAP],
     AC_CACHE_CHECK([for working bswap_16, bswap_32, bswap_64],
       [gl_cv_header_working_byteswap_h],
       [gl_cv_header_working_byteswap_h=no
+       dnl Check that floating point arguments work.
+       dnl This also checks C libraries with implementations like
+       dnl '#define bswap_16(x) (((x) >> 8 & 0xff) | (((x) & 0xff) << 8))'
+       dnl that mistakenly evaluate their arguments multiple times.
        AC_COMPILE_IFELSE(
          [AC_LANG_PROGRAM(
             [[#include <byteswap.h>
-- 
2.40.1

Reply via email to