bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

i386 byteswap.h provoking ``may be undefined'' warnings in gcc3


From: Paul Haahr
Subject: i386 byteswap.h provoking ``may be undefined'' warnings in gcc3
Date: Wed, 11 Jul 2001 15:56:54 -0700 (PDT)

Gcc 3.0's new ``warning: operation on `p' may be undefined'' is
(spuriously?) provoked by glibc's <bits/byteswap.h> code for the x86.

Consider the following snippet:

    #include <byteswap.h>

    unsigned long long f(unsigned long long n)
    {
        unsigned short x = bswap_16(n++);
        unsigned long y = bswap_32(n++);
        unsigned long long z = bswap_64(n++);
        return x + y + z;
    }

The bswap_16 and bswap_32 macros expand into horrible creatures, where a
reference to n++ appears several times in one expression.  This generates
one warning for the call to bswap_16 and three for the call to bswap_32.
However, evaluation of the problematic expressions is gated by an
``if (__builtin_constant_p(x))'' test which always evaluates to false if
there are internal side effects, so the ``may be undefined'' path is
never actually taken.

I can't quite tell if this is a gcc bug or a glibc bug, but I've
attached a workaround that lives in glibc.  It appears to still constant
fold properly, and generate identical code to the old version, for a few
small test cases.

Fixing this in gcc would require not issuing this kind of warning (and
perhaps others) in code that isn't evaluated due to a __builtin_constant_p
test.

--p

--- /usr/include/bits/byteswap.h        Sun Nov 19 06:24:03 2000
+++ bits/byteswap.h     Wed Jul 11 15:22:48 2001
@@ -29,9 +29,10 @@
 # define __bswap_16(x) \
      (__extension__                                                          \
       ({ register unsigned short int __v;                                    \
-        if (__builtin_constant_p (x))                                        \
-          __v = __bswap_constant_16 (x);                                     \
-        else                                                                 \
+        if (__builtin_constant_p (x)) {                                      \
+          register unsigned short int __x = x;                               \
+          __v = __bswap_constant_16 (__x);                                   \
+        } else                                                               \
           __asm__ __volatile__ ("rorw $8, %w0"                               \
                                 : "=r" (__v)                                 \
                                 : "0" ((unsigned short int) (x))             \
@@ -55,9 +56,10 @@
 #  define __bswap_32(x) \
      (__extension__                                                          \
       ({ register unsigned int __v;                                          \
-        if (__builtin_constant_p (x))                                        \
-          __v = __bswap_constant_32 (x);                                     \
-        else                                                                 \
+        if (__builtin_constant_p (x)) {                                      \
+          register unsigned int __x = x;                                     \
+          __v = __bswap_constant_32 (__x);                                   \
+        } else                                                               \
           __asm__ __volatile__ ("rorw $8, %w0;"                              \
                                 "rorl $16, %0;"                              \
                                 "rorw $8, %w0"                               \



reply via email to

[Prev in Thread] Current Thread [Next in Thread]