https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70526
--- Comment #2 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Markus Trippelsdorf from comment #1)
> -Wstrict-aliasing=2 warns:
>
> markus@x4 tmp % g++ -O2 -Wstrict-aliasing=2 test_fire.cpp
> test_fire.cpp: In instantiation of ‘const T* AlignedStorage2<T>::addr()
> const [with T = Register]’:
> test_fire.cpp:41:52: required from here
> test_fire.cpp:13:34: warning: dereferencing type-punned pointer will break
> strict-aliasing rules [-Wstrict-aliasing]
> const T* addr() const { return reinterpret_cast<const T*>(u.mBytes); }
>
> -fno-strict-aliasing fixes the issue, thus invalid.
Isn't that a bit fast? -Wstrict-aliasing=3 doesn't warn, the read and the write
are both done in type Register. Reducing a bit:
typedef unsigned uint32_t;
template<typename T>
struct AlignedStorage2
{
char mBytes[sizeof(T)];
const T* addr() const { return reinterpret_cast<const T*>(mBytes); }
T* addr() { return reinterpret_cast<T*>(mBytes); }
};
struct Register {
uint32_t reg_;
};
class TypedOrValueRegister
{
AlignedStorage2<Register> typed;
__attribute__((noinline)) Register& dataTyped() { return *typed.addr(); }
public:
TypedOrValueRegister(Register reg)
{
dataTyped() = reg;
}
Register typedReg() const { return *typed.addr(); }
};
int main() {
Register reg = { 10u };
if (TypedOrValueRegister(reg).typedReg().reg_ != 10)
__builtin_abort();
return 0;
}