[Top][All Lists]
[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" \
- i386 byteswap.h provoking ``may be undefined'' warnings in gcc3,
Paul Haahr <=