mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
ip2net: i hate strict aliasing
This commit is contained in:
parent
1fcee44443
commit
3842cbbca5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
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];
|
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];
|
a_addr[1] &= b_addr[1];
|
||||||
memcpy(result->s6_addr, a_addr, 16);
|
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)
|
static void rtrim(char *s)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user