This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Sorry to mention aliasing again, but is the standard IN6_ARE_ADDR_EQUAL really wrong?


    Hello,

  I don't want to reopen the long-rumbling discussion about what gcc ought to
/want/ to do; I'd just like to know if warning in this case is indeed what it
wants to do.  The standard definition of IN6_ARE_ADDR_EQUAL looks a bit like this:

#define IN6_ARE_ADDR_EQUAL(a, b) \
	(((const uint32_t *)(a))[0] == ((const uint32_t *)(b))[0] \
	 && ((const uint32_t *)(a))[1] == ((const uint32_t *)(b))[1] \
	 && ((const uint32_t *)(a))[2] == ((const uint32_t *)(b))[2] \
	 && ((const uint32_t *)(a))[3] == ((const uint32_t *)(b))[3])

  That's cygwin's, but glibc is roughly the same (modulo s/const/__const/g).

  Anyhow it gives a strict aliasing warning now, that it didn't used to in
4.3.4: reduced testcase is

---------------------------------------------------------------------
$ cat walias1.c

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;

struct in6_addr
{
  uint8_t __s6_addr[16];
};

static inline int
address_in_use (unsigned char *a, struct in6_addr *in6)
{
  if ((((const uint32_t *)(a))[0]
                == ((const uint32_t *)(in6->__s6_addr))[0]
    && ((const uint32_t *)(a))[1]
                == ((const uint32_t *)(in6->__s6_addr))[1]
    && ((const uint32_t *)(a))[2]
                == ((const uint32_t *)(in6->__s6_addr))[2]
    && ((const uint32_t *)(a))[3]
                == ((const uint32_t *)(in6->__s6_addr))[3]))
    return 1;

  return 0;
}

admin@ubik /tmp/warning
$ /usr/bin/gcc-4 -c walias1.c -Wstrict-aliasing -O2

admin@ubik /tmp/warning
$ gcc-4 -c walias1.c -Wstrict-aliasing -O2
walias1.c: In function 'address_in_use':
walias1.c:14:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules
---------------------------------------------------------------------

  Is that really right?  The type of the pointer (in6->__s6_addr) that we're
casting is unsigned char *, so shouldn't it already alias everything anyway
and dereferencing it be allowed, like it is for the casted (a)?  I'll file a
PR if so.  (I can't pretend I find the language in the spec easy to follow.)

    cheers,
      DaveK



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]