Browse Source

ip2net: i hate strict aliasing

pull/127/head
bol-van 3 years ago
parent
commit
3842cbbca5
  1. BIN
      binaries/aarch64/ip2net
  2. BIN
      binaries/arm/ip2net
  3. BIN
      binaries/freebsd-x64/ip2net
  4. BIN
      binaries/mips32r1-lsb/ip2net
  5. BIN
      binaries/mips32r1-msb/ip2net
  6. BIN
      binaries/mips64r2-msb/ip2net
  7. BIN
      binaries/ppc/ip2net
  8. BIN
      binaries/x86/ip2net
  9. BIN
      binaries/x86_64/ip2net
  10. 27
      ip2net/ip2net.c

BIN
binaries/aarch64/ip2net

Binary file not shown.

BIN
binaries/arm/ip2net

Binary file not shown.

BIN
binaries/freebsd-x64/ip2net

Binary file not shown.

BIN
binaries/mips32r1-lsb/ip2net

Binary file not shown.

BIN
binaries/mips32r1-msb/ip2net

Binary file not shown.

BIN
binaries/mips64r2-msb/ip2net

Binary file not shown.

BIN
binaries/ppc/ip2net

Binary file not shown.

BIN
binaries/x86/ip2net

Binary file not shown.

BIN
binaries/x86_64/ip2net

Binary file not shown.

27
ip2net/ip2net.c

@ -102,7 +102,14 @@ static inline const struct in6_addr *mask_from_bitcount6(uint32_t zct)
}
// result = a & b
/*
// this is "correct" solution for strict aliasing feature
// but I don't like this style of coding
// write what I don't mean to force smart optimizer to do what it's best
// it produces better code sometimes but not on all compilers/versions/archs
// sometimes it even generates real memcpy calls (mips32,arm32)
// so I will not do it
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
{
uint64_t a_addr[2], b_addr[2];
@ -112,6 +119,24 @@ static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct i
a_addr[1] &= b_addr[1];
memcpy(result->s6_addr, a_addr, 16);
}
*/
// YES, from my point of view C should work as a portable assembler. It must do what I instruct it to do.
// that's why I disable strict aliasing for this function. I observed gcc can miscompile with O2/O3 setting if inlined and not coded "correct"
// result = a & b
#if defined(__GNUC__) && !defined(__llvm__)
__attribute__((optimize ("no-strict-aliasing")))
#endif
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
{
#ifdef __SIZEOF_INT128__
// gcc and clang have 128 bit int types on some 64-bit archs. take some advantage
*((unsigned __int128*)result->s6_addr) = *((unsigned __int128*)a->s6_addr) & *((unsigned __int128*)b->s6_addr);
#else
((uint64_t*)result->s6_addr)[0] = ((uint64_t*)a->s6_addr)[0] & ((uint64_t*)b->s6_addr)[0];
((uint64_t*)result->s6_addr)[1] = ((uint64_t*)a->s6_addr)[1] & ((uint64_t*)b->s6_addr)[1];
#endif
}
static void rtrim(char *s)
{

Loading…
Cancel
Save