Launchpad has imported 11 comments from the remote bug at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38341.
If you reply to an imported comment from within Launchpad, your comment will be sent to the remote bug automatically. Read more about Launchpad's inter-bugtracker facilities at https://help.launchpad.net/InterBugTracking. ------------------------------------------------------------------------ On 2008-12-01T08:35:08+00:00 Fredrik-hederstierna wrote: Compiler gives wrong warning for "comparison of promoted ~unsigned with unsigned" when compiling with ARM-ELF. Submit script for building arm-elf toolchain and testcode. Compilation using; arm-elf-gcc -c cast.c -W cast.c: In function 'test_cast': cast.c:13: warning: comparison of promoted ~unsigned with unsigned Best Regards Fredrik Hederstierna ============ FILE: cast.c ============ typedef unsigned char u8_t; void test_cast(void) { unsigned char c1 = 0; unsigned char c2 = 0; u8_t u1 = 0; u8_t u2 = 0; if (c1 == (unsigned char)(~c2)) { } if (u1 == (u8_t)(~u2)) { // THIS WILL GIVE WARNING } } ======================== FILE: build_toolchain.sh ======================== set -e -x TARGET=arm-elf BINUTILS_VERSION=2.19 GCC_VERSION=4.3.2 NEWLIB_VERSION=1.16.0 GDB_VERSION=6.8 INSIGHT_VERSION=6.8 DEST="/usr/local/gcc/arm-elf-tools-$GCC_VERSION" BINUTILS_DIR="binutils-$BINUTILS_VERSION" GCC_DIR="gcc-$GCC_VERSION" NEWLIB_DIR="newlib-$NEWLIB_VERSION" GDB_DIR="gdb-$GDB_VERSION" INSIGHT_DIR="insight-$INSIGHT_VERSION" # set rwx access umask 022 # unpack tar-balls rm -fr "$BINUTILS_DIR" "$GCC_DIR" "$NEWLIB_DIR" "$GDB_DIR" "$INSIGHT_DIR" tar xvjf "binutils-$BINUTILS_VERSION.tar.bz2" tar xvjf "gcc-$GCC_VERSION.tar.bz2" tar xvzf "newlib-$NEWLIB_VERSION.tar.gz" tar xvjf "gdb-$GDB_VERSION.tar.bz2" tar xvjf "insight-$INSIGHT_VERSION.tar.bz2" cd "$GCC_DIR" ln -s "../$NEWLIB_DIR/newlib" newlib ln -s "../$NEWLIB_DIR/libgloss" libgloss cd .. rm -fr build mkdir -p build/binutils build/gcc build/gdb build/insight build/newlib # Build binutils cd build/binutils "../../$BINUTILS_DIR/configure" --target="$TARGET" --prefix="$DEST" --disable-nls make LDFLAGS=-s all install # Build GCC cd ../gcc PATH="$DEST/bin:$PATH" "../../$GCC_DIR/configure" --enable-languages=c,c++ --target="$TARGET" --prefix="$DEST" --with-gnu-as --with-gnu-ld --disable-nls --with-newlib --disable-__cxa_atexit --with-ecos make LDFLAGS=-s all all-gcc all-target-libstdc++-v3 install install-gcc install-target-libstdc++-v3 # Build GDB and Insight cd ../gdb # Without insight "../../$GDB_DIR/configure" --target="$TARGET" --prefix="$DEST" make -w all install cd ../insight # With insight "../../$INSIGHT_DIR/configure" --target="$TARGET" --prefix="$DEST" make -w all install # Remove uncompressed sources cd ../.. rm -fr "$BINUTILS_DIR" "$GCC_DIR" "$NEWLIB_DIR" "$GDB_DIR" "$INSIGHT_DIR" build Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/1 ------------------------------------------------------------------------ On 2008-12-01T10:01:23+00:00 Rguenth wrote: /* Warn if two unsigned values are being compared in a size larger than their original size, and one (and only one) is the result of a `~' operator. This comparison will always fail. Also warn if one operand is a constant, and the constant does not have all bits set that are set in the ~ operand when it is extended. */ note that integer promotion is done on the operand(!) of ~. So u1 == (u8_t)(~u2) is equal to (int)u1 == (int)(u8_t)(~(int)u2) that we do not warn for the first case is because it is optimized to u1 == ~u2 before. Why do you think the warning is incorrect? Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/2 ------------------------------------------------------------------------ On 2008-12-01T12:40:29+00:00 Fredrik-hederstierna wrote: Then why dont we get warning on the first if-statement? Shouldnt these lines be equal? if (c1 == (unsigned char)(~c2)) { } if (u1 == (u8_t)(~u2)) { // THIS WILL GIVE WARNING } The first if-statement does not give warnings, should this be evaluated the same way? if ((int)c1 == (int)(unsigned char)(~(int)c2)) { My idea was that either of the if-statements are wrong. Either both or none should give warnings, or am I wrong? The typedef to "unsigned char" should be the same as using primitive types regarding this warning, or? Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/3 ------------------------------------------------------------------------ On 2008-12-01T12:49:36+00:00 Rguenth wrote: As I said, for the first case we optimize away the promotions before the warning code comes along. Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/4 ------------------------------------------------------------------------ On 2008-12-01T12:55:13+00:00 Fredrik-hederstierna wrote: Heres another example, then I do not think the warnings are due to optimization. I have same warnings with both -O0 and -O3. #include <stdio.h> typedef unsigned char u8_t; void test_cast(unsigned char c1, unsigned char c2, u8_t u1, u8_t u2) { if (c1 == (unsigned char)(~c2)) { printf("No warning"); } if (c1 == ~c2) { printf("This gives warning"); } if (u1 == (u8_t)(~u2)) { printf("This gives warning"); } if ((unsigned char)u1 == (unsigned char)(~u2)) { printf("This gives warning"); } } The original code that caused this warnings are the TCP/IP stack lwIP, then I constructed this minimal example. Original code from lwIP TCP/IP stack: ------------------------------------- static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8) + 1]; static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; /.../ if (ip_reassbitmap[ip_reasslen / (8 * 8)] != (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) { /.../ Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/5 ------------------------------------------------------------------------ On 2008-12-01T13:35:12+00:00 Fredrik-hederstierna wrote: On Intel i386-GCC (4.2.3) we just get warning only for the line if (c1 == ~c2) The other lines does not give warnings, so maybe its just the ARM- backend that catch this warning. I guess you mean that for ARM target the optimization tree does things that silence the warning. Is it good that optimizations can silence possible warnings/errors? And that it differs depending on which backend I'm running? Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/6 ------------------------------------------------------------------------ On 2008-12-02T12:12:03+00:00 Rguenth wrote: *** Bug 38370 has been marked as a duplicate of this bug. *** Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/7 ------------------------------------------------------------------------ On 2009-02-23T23:53:17+00:00 John Carter wrote: R Guenther said... > (int)u1 == (int)(u8_t)(~(int)u2) > > that we do not warn for the first case is because it is optimized to > u1 == ~u2 before. > > Why do you think the warning is incorrect? ----------------------------------------------- I would expect u2 to be promoted to a 4 byte int ~ to do the ones complement on a 4 byte int (unsigned char)~u2 to truncate to one byte discarding the most significant 3 bytes and then the result get promoted to an int to evaluate the == ie. The cast cannot get optimized away, it's not a null op, it discards the most significant bytes. ie. (int)(unsigned char)~(int)u2 is not equivalent to ~(int)u2 ie. This is a bug Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/8 ------------------------------------------------------------------------ On 2009-02-24T00:40:28+00:00 Michael-malone wrote: #ifdef UINT #include <stdint.h> #define TYPE uint16_t #else #define TYPE unsigned short int #endif #define VALUE 0xFF int main(void); int main() { TYPE variable_a = ~VALUE; TYPE variable_b = VALUE; TYPE result; #ifdef ASSIGN TYPE tmp = ~variable_a; result = (variable_b == tmp); #else result = (variable_b == (TYPE) ~variable_a); #endif return 0; } Further to John's input, here is a sample program which shows up why this bug is interesting. When one uses a typedef'd type, the promoted comparison warning is displayed. When one does not, it isn't! This is not the case for gcc-4.2.3 -both variants compile without warnings. The compile commands I used were: gcc gcc_bug.c -W -Wall -o bug and gcc gcc_bug.c -W -Wall -DUINT -o bug Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/9 ------------------------------------------------------------------------ On 2009-02-24T00:43:39+00:00 Michael-malone wrote: I forgot to mention, if you assign to an intermediate variable, the warning also disappears which is the behaviour I would expect from an explicit cast. Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/10 ------------------------------------------------------------------------ On 2014-01-29T16:00:58+00:00 Gjl wrote: This is still present for 4.8.2 and current trunk (future 4.9.0). C++ works fine, i.e. just the warnings that I'd expect. As this works as expected in good old 3.4.x, shouldn't this be marked as regression? Reply at: https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/291780/comments/11 ** Changed in: gcc Status: New => Confirmed -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/291780 Title: [PR38370] inconsistent warnings when comparing uint8_t vs. unsigned char To manage notifications about this bug go to: https://bugs.launchpad.net/gcc/+bug/291780/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
