From e747c9b5b6d3440fcacc5e2dae6679a8f83ea7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 7 Jul 2013 14:24:48 +0200 Subject: [PATCH] GCC 4.5 compatibility: ICE and miscompiled binary operators. It seems that in this particular case `a &= b` is not doing the same as `a = a & b`. In Release build the expression is miscompiled (it always resets `a` to zero), in Debug build it triggers ICE: Object.hpp:280:9: internal compiler error: in make_decl_rtl, at varasm.c:1318 Possibly related to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43880. Changed to `a = a & b` in all cases, now SceneGraphObject test passes again. Outside of Object (e.g. in Corrade's EnumSet tests) this is not reproducible, wtf. Moreover, classic solution, `-fno-strict-aliasing` didn't help at all here. Probably caused by some other optimization, IMHO. --- src/SceneGraph/Object.hpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/SceneGraph/Object.hpp b/src/SceneGraph/Object.hpp index e88dd7857..2ad4da7f7 100644 --- a/src/SceneGraph/Object.hpp +++ b/src/SceneGraph/Object.hpp @@ -277,7 +277,14 @@ template std::vector Ob /* All not-already cleaned objects (...duplicate occurences) should have joint mark */ CORRADE_INTERNAL_ASSERT((*it)->counter = 0xFFFFu || (*it)->flags & Flag::Joint); + #ifndef CORRADE_GCC45_COMPATIBILITY (*it)->flags &= ~Flag::Joint; + #else + /* Miscompiled in Release build, causes ICE in Debug build: + internal compiler error: in make_decl_rtl, at varasm.c:1318 + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43880 */ + (*it)->flags = (*it)->flags & ~Flag::Joint; + #endif (*it)->counter = 0xFFFFu; } @@ -300,7 +307,13 @@ template typename Transformation::DataType Objectflags & Flag::Visited); + #ifndef CORRADE_GCC45_COMPATIBILITY o->flags &= ~Flag::Visited; + #else + /* Miscompiled (the above assertion is triggered later), see above for + more information */ + o->flags = o->flags & ~Flag::Visited; + #endif Object* parent = o->parent(); @@ -355,7 +368,13 @@ template void Object::setClean(std::vector /* Cleanup all marks */ for(auto it = objects.begin(); it != objects.end(); ++it) + #ifndef CORRADE_GCC45_COMPATIBILITY (*it)->flags &= ~Flag::Visited; + #else + /* Miscompiled (not all objects are cleaned), see above for more + information */ + (*it)->flags = (*it)->flags & ~Flag::Visited; + #endif /* Compute absolute transformations */ Scene* scene = objects[0]->scene(); @@ -403,7 +422,13 @@ template void Object::setClean(const typen } /* Mark object as clean */ + #ifndef CORRADE_GCC45_COMPATIBILITY flags &= ~Flag::Dirty; + #else + /* Miscompiled (not all objects are cleaned), see above for more + information */ + flags = flags & ~Flag::Dirty; + #endif } }}