This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/70526] GCC 6 miscompiles Firefox JIT compiler
- From: "glisse at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 04 Apr 2016 12:54:45 +0000
- Subject: [Bug rtl-optimization/70526] GCC 6 miscompiles Firefox JIT compiler
- Auto-submitted: auto-generated
- References: <bug-70526-4 at http dot gcc dot gnu dot org/bugzilla/>
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;
}