ImageEngine/gaffer — pull request #853 by johnhaddon (2014-05-30 17:39:06+00:00)
Title: Strict aliasing shenanigans

This fixes the crash reported by Hradec here :

https://groups.google.com/forum/#!topic/gaffer-dev/PR4n1tOaH6o

That crash occurred in the constructor for Gaffer::Context, but I narrowed it down to an interaction between GCC 4.1.2 on CentOS and boost::flat_map (which is now used internally in Gaffer::Context). The following code alone was sufficient to segfault when compiled with `-O2` :

```
typedef boost::container::flat_map Map;

for( int i = 0; i < 100000; ++i )
{
Map map;
int &s = map[i];
std::cerr << map.size() << " " << s << std::endl;
}
```

Curiously enough this didn't crash with either GCC 4.2.1 on OS X or with GCC 4.4.7 on CentOS. With a little investigation I discovered that the specific optimisation flag that triggered the problem was `-fstrict-aliasing`, which is turned on by default in GCC with `-O2`. boost::flat_map breaks the strict aliasing rule in boost::container_detail::force_copy(), which it calls liberally. I did a bit of learning about what this all meant - the link below is a pretty decent description of the strict aliasing rules and what to do about them for anyone interested :

http://dbp-consulting.com/tutorials/StrictAliasing.html

I also found this rant by none other than Linus Torvalds, berating the GCC team for applying the strict aliasing rules so vigorously as to defy common sense :

http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg01647.html

I then discovered that Apple actually disable `-fstrict-aliasing` in `-O2` mode, presumably for the reasons stated in the rant. But I also tested with it turned on explicitly and it was OK with GCC 4.2.1 on OS X anyway. It's also OK in Linux with GCC 4.4.7.

The fix I'm proposing is to disable `-fstrict-aliasing` if and only if the compiler is GCC 4.1.2 and we're on Linux. This both fixes the problem at hand and allows us to remove the old `-Wno-strict-aliasing` flag we were using to disable other warnings from boost which would otherwise have stopped the build. So all recent compilers stay the same, except we get better error reporting for our own code (I've included a fix for another problem shown up by this). There may be some performance loss in the GCC 4.1.2 build, but since it turns out we weren't using that optimisation on OS X anyway, I'm not sure how much to worry about that. If you have specific areas of performance you'd like me to test I could do that though.

I've tested the small boost-only test case and Gaffer itself with this new set of flags in the following configurations :

- CentOS 6, GCC 4.1.2. (IE internal build).
- CentOS 6, GCC 4.4.7. (Public build).
- OS X 10.7.5, GCC 4.2.1. (My development build).