Skip to content
Snippets Groups Projects
Commit 528b5f36 authored by Steffen Müthing's avatar Steffen Müthing
Browse files

Work around a nasty compiler bug in GCC 6.3

GCC 6.3 errors out with an ICE or simply hangs when instantiating a certain variant of operator^= on
BitSetVectorReference. This patch works around the problem by forcing the actual XOR instruction
into a separate function for that compiler. The workaround is probably horribly slow, but it
shouldn't have any impact on unaffected compilers.

This probably needs backporting.
parent 95fd84b0
No related branches found
No related tags found
1 merge request!528Work around a nasty compiler bug in GCC 6.3
Pipeline #10264 passed
......@@ -315,11 +315,31 @@ namespace Dune {
return *this;
}
private:
// For some reason, the following variant of operator^= triggers an ICE or a hanging
// compiler on Debian 9 with GCC 6.3 and full optimizations enabled (-O3).
// The only way to reliably avoid the issue is by making sure that the compiler does not
// see the XOR in the context of the function, so here is a little helper that will normally
// be inlined, but not on the broken compiler. This incurs a substantial overhead (a function
// call), but until someone else has a better idea, it's the only way to make it work reliably.
static bool xor_helper(bool a, bool b)
#if defined(__GNUC__) && ! defined(__clang__) && __GNUC__ == 6 && __GNUC_MINOR__ == 3 && __cplusplus \
== 201402L
__attribute__((noinline))
#endif
;
public:
//! Bitwise exclusive or (for BitSetVectorConstReference and BitSetVectorReference)
BitSetVectorReference& operator^=(const BitSetVectorConstReference& x)
{
// This uses the helper from above to hoist the actual XOR computation out of the function for
// the buggy version of GCC.
for (size_type i=0; i<block_size; i++)
getBit(i) = (test(i) ^ x.test(i));
getBit(i) = xor_helper(test(i),x.test(i));
return *this;
}
......@@ -399,6 +419,14 @@ namespace Dune {
}
};
// implementation of helper - I put it into the template to avoid having
// to compile it in a dedicated compilation unit
template<int block_size, class Alloc>
bool BitSetVectorReference<block_size,Alloc>::xor_helper(bool a, bool b)
{
return a ^ b;
}
/**
typetraits for BitSetVectorReference
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment