Browse Source

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.
Vladimír Vondruš 13 years ago
parent
commit
e747c9b5b6
  1. 25
      src/SceneGraph/Object.hpp

25
src/SceneGraph/Object.hpp

@ -277,7 +277,14 @@ template<class Transformation> std::vector<typename Transformation::DataType> 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<class Transformation> typename Transformation::DataType Object<Transfor
for(;;) {
/* Clean visited mark */
CORRADE_INTERNAL_ASSERT(o->flags & 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<Transformation>* parent = o->parent();
@ -355,7 +368,13 @@ template<class Transformation> void Object<Transformation>::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<Transformation>* scene = objects[0]->scene();
@ -403,7 +422,13 @@ template<class Transformation> void Object<Transformation>::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
}
}}

Loading…
Cancel
Save