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

[!528] 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.

See merge request !528

(cherry picked from commit 9a9fceea)

528b5f36 Work around a nasty compiler bug in GCC 6.3
parent ae81300a
Branches
Tags
3 merge requests!586Centralize CI config for 2.6 release,!531Update CI for 2.6 release branch,!529[backport:2.6] [!528] Work around a nasty compiler bug in GCC 6.3
Pipeline #10266 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.
Please register or to comment