diff --git a/.github/workflows/verify-pull-request.yml b/.github/workflows/verify-pull-request.yml index da4ea56..ccaedad 100644 --- a/.github/workflows/verify-pull-request.yml +++ b/.github/workflows/verify-pull-request.yml @@ -8,6 +8,7 @@ jobs: strategy: matrix: cpp-compiler: ["clang", "gcc"] + options: ["-c opt", ""] steps: - uses: actions/checkout@v4 - uses: bazel-contrib/setup-bazel@0.8.5 @@ -16,7 +17,7 @@ jobs: disk-cache: "verify-pr:run-bazel-tests:${{ matrix.cpp-compiler }}" repository-cache: true - run: echo "CC=${{ matrix.cpp-compiler }}" >> $GITHUB_ENV - - run: bazel test ... + - run: bazel test ${{ matrix.options }} ... check-formatting: name: "Check Python formatting" runs-on: ubuntu-latest diff --git a/runtime/cpp/emboss_defines.h b/runtime/cpp/emboss_defines.h index e247d00..24b5af0 100644 --- a/runtime/cpp/emboss_defines.h +++ b/runtime/cpp/emboss_defines.h @@ -161,6 +161,27 @@ static_cast((offset))) #endif // !defined(EMBOSS_CHECK_POINTER_ALIGNMENT) +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033 +// +// This affects Emboss: without the fix in the appropriate bug, we get a +// miscompilation for some Emboss code, including some unit tests. +// +// It is not known whether the workaround on the Emboss side is complete, so +// the recommendation is to move to a version of GCC that is not affected. +// However, changing toolchains can be difficult, so we do provide a +// workaround. +#if !defined(EMBOSS_GCC_BUG_115033) +#if defined(__clang__) +#define EMBOSS_GCC_BUG_115033 0 +#elif __GNUC__ >= 12 && __GNUC__ <= 13 +#define EMBOSS_GCC_BUG_115033 1 +#elif __GNUC__ == 14 && __GNUC_MINOR__ < 2 +#define EMBOSS_GCC_BUG_115033 1 +#else +#define EMBOSS_GCC_BUG_115033 0 +#endif +#endif + // EMBOSS_NO_OPTIMIZATIONS is used to turn off all system-specific // optimizations. This is mostly intended for testing, but could be used if // optimizations are causing problems. diff --git a/runtime/cpp/emboss_memory_util.h b/runtime/cpp/emboss_memory_util.h index 09be2f1..fca71c9 100644 --- a/runtime/cpp/emboss_memory_util.h +++ b/runtime/cpp/emboss_memory_util.h @@ -412,8 +412,28 @@ class ContiguousBuffer final { explicit ContiguousBuffer(::std::nullptr_t) : bytes_{nullptr}, size_{0} {} // Implicitly construct or assign a ContiguousBuffer from a ContiguousBuffer. +#if !EMBOSS_GCC_BUG_115033 ContiguousBuffer(const ContiguousBuffer &other) = default; - ContiguousBuffer& operator=(const ContiguousBuffer& other) = default; + ContiguousBuffer &operator=(const ContiguousBuffer &other) = default; +#else + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033 for details on the + // bug (determined by bisecting GCC). + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114207 may also be relevant. + // + // A minimized example is available at https://godbolt.org/z/489z7z135 + // + // It is not entirely clear how these definitions work around the GCC bug, + // but they appear to. One notable difference (and also the main reason that + // we only use these definitions for affected versions of GCC) is that they + // change the ABI of ContiguousBuffer, at least in the minimized case. + ContiguousBuffer(const ContiguousBuffer &other) + : bytes_{other.bytes_}, size_{other.size_} {} + ContiguousBuffer &operator=(const ContiguousBuffer &other) { + bytes_ = other.bytes_; + size_ = other.size_; + return *this; + } +#endif // Explicitly construct a ContiguousBuffers from another, compatible // ContiguousBuffer. A compatible ContiguousBuffer has an