gcc 4.3.0, -Wconversion against -O1

View: New views
3 Messages — Rating Filter:   Alert me  

gcc 4.3.0, -Wconversion against -O1

by Bugzilla from avg@icyb.net.ua :: Rate this Message:

| View Threaded | Show Only this Message


There is a very simple function:
/******** func.c **********/
#include <netinet/in.h>

uint16_t my_htons(uint16_t hostshort)
{
         return htons(hostshort);
}
/**************************/

$ cc func.c -Wconversion -Werror -c -o func.o
Exit 0

$ cc func.c -O1 -Wconversion -Werror -c -o func.o
cc1: warnings being treated as errors
func.c: In function ‘my_htons’:
func.c:5: error: conversion to ‘short unsigned int’ from ‘int’ may alter
its value
Exit 1

Adding -E flag I get the following code:
...
# 2 "func.c" 2

uint16_t my_htons(uint16_t hostshort)
{
  return (__extension__ ({ register unsigned short int __v, __x =
(hostshort); if (__builtin_constant_p (__x)) __v = ((((__x) >> 8) &
0xff) | (((__x) & 0xff) << 8)); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }));
}


Is there anything (smart) that either I or gcc or glibc/linux can do
about this?
No type-casts in *my* code help.

The warning seems to be uncalled for in this case, because I don't see
explicit 'int' type anywhere in the expanded code.

P.S. the code seems to be coming from /usr/include/bits/byteswap.h,
__bswap_16() macro in this way:

======= netinet/in.h =======
#ifdef __OPTIMIZE__
/* We can optimize calls to the conversion functions.  Either nothing has
    to be done or we are using directly the byte-swapping functions which
    often can be inlined.  */
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
    so these functions are all just identity.  */
# define ntohl(x)       (x)
# define ntohs(x)       (x)
# define htonl(x)       (x)
# define htons(x)       (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
#   define ntohl(x)     __bswap_32 (x)
#   define ntohs(x)     __bswap_16 (x)
#   define htonl(x)     __bswap_32 (x)
#   define htons(x)     __bswap_16 (x)
#  endif
# endif
#endif

--
Andriy Gapon

Re: gcc 4.3.0, -Wconversion against -O1

by Richard Guenther-2 :: Rate this Message:

| View Threaded | Show Only this Message

On Fri, Sep 19, 2008 at 5:03 PM, Andriy Gapon <avg@...> wrote:

>
> There is a very simple function:
> /******** func.c **********/
> #include <netinet/in.h>
>
> uint16_t my_htons(uint16_t hostshort)
> {
>        return htons(hostshort);
> }
> /**************************/
>
> $ cc func.c -Wconversion -Werror -c -o func.o
> Exit 0
>
> $ cc func.c -O1 -Wconversion -Werror -c -o func.o
> cc1: warnings being treated as errors
> func.c: In function 'my_htons':
> func.c:5: error: conversion to 'short unsigned int' from 'int' may alter its
> value
> Exit 1
>
> Adding -E flag I get the following code:
> ...
> # 2 "func.c" 2
>
> uint16_t my_htons(uint16_t hostshort)
> {
>  return (__extension__ ({ register unsigned short int __v, __x =
> (hostshort); if (__builtin_constant_p (__x)) __v = ((((__x) >> 8) & 0xff) |
> (((__x) & 0xff) << 8)); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0"
> (__x) : "cc"); __v; }));

The computation ((((__x) >> 8) & 0xff) |  (((__x) & 0xff) << 8)) is promoted
to int as of C language standards rules and the store to __v truncates it.

The warning isn't clever enough to see that this doesn't happen due to
the masking applied, and in general there are always cases that would
slip through.

Richard.

Re: gcc 4.3.0, -Wconversion against -O1

by Bugzilla from lopezibanez@gmail.com :: Rate this Message:

| View Threaded | Show Only this Message

2008/9/19 Richard Guenther <richard.guenther@...>:
>
> The computation ((((__x) >> 8) & 0xff) |  (((__x) & 0xff) << 8)) is promoted
> to int as of C language standards rules and the store to __v truncates it.
>
> The warning isn't clever enough to see that this doesn't happen due to
> the masking applied, and in general there are always cases that would
> slip through.

-Wconversion had some fixes in this area during GCC 4.4 (and I think
there is still at least one pending patch). Could you re-test with a
recent trunk snapshot? I cannot do it myself.

Cheers,

Manuel.