From 4b7412926f6b9004d9ecf1d59adc14c64956ac10 Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Tue, 29 Oct 2024 19:55:44 +0100 Subject: [PATCH] [INFRA] Extend SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY --- .clang-format | 2 + .../aligned_sequence_concept.hpp | 9 +--- .../detail/score_matrix_single_column.hpp | 9 +--- .../container/concatenated_sequences.hpp | 12 ++--- include/seqan3/core/platform.hpp | 54 +++++++++++++++++-- .../seqan3/utility/container/small_vector.hpp | 9 +--- .../container/container_concept_test.cpp | 31 +++-------- ...bug_stream_container_of_container_test.cpp | 10 +--- test/unit/search/search_scheme_test.cpp | 2 +- 9 files changed, 74 insertions(+), 64 deletions(-) diff --git a/.clang-format b/.clang-format index 5ec6e1c4d4..da256fbeb2 100644 --- a/.clang-format +++ b/.clang-format @@ -272,4 +272,6 @@ WhitespaceSensitiveMacros: - NS_SWIFT_NAME - PP_STRINGIZE - STRINGIZE + - SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START + - SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP ... diff --git a/include/seqan3/alignment/aligned_sequence/aligned_sequence_concept.hpp b/include/seqan3/alignment/aligned_sequence/aligned_sequence_concept.hpp index 4456822346..3931b1499e 100644 --- a/include/seqan3/alignment/aligned_sequence/aligned_sequence_concept.hpp +++ b/include/seqan3/alignment/aligned_sequence/aligned_sequence_concept.hpp @@ -374,14 +374,9 @@ inline void assign_unaligned(aligned_seq_t & aligned_seq, unaligned_sequence_typ using std::swap; aligned_seq_t tmp; tmp.resize(std::ranges::distance(unaligned_seq)); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wstringop-overflow) std::ranges::copy(unaligned_seq, std::ranges::begin(tmp)); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP swap(aligned_seq, tmp); } //!\} diff --git a/include/seqan3/alignment/matrix/detail/score_matrix_single_column.hpp b/include/seqan3/alignment/matrix/detail/score_matrix_single_column.hpp index fb1bb8fe9e..ef764d1045 100644 --- a/include/seqan3/alignment/matrix/detail/score_matrix_single_column.hpp +++ b/include/seqan3/alignment/matrix/detail/score_matrix_single_column.hpp @@ -113,14 +113,9 @@ class score_matrix_single_column this->number_of_columns = number_of_columns.get(); optimal_column.clear(); horizontal_column.clear(); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wstringop-overflow) optimal_column.resize(number_of_rows.get(), initial_value); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP horizontal_column.resize(number_of_rows.get(), initial_value); vertical_column = views::repeat_n(initial_value, number_of_rows.get()); } diff --git a/include/seqan3/alphabet/container/concatenated_sequences.hpp b/include/seqan3/alphabet/container/concatenated_sequences.hpp index d3e616594a..41b74acae1 100644 --- a/include/seqan3/alphabet/container/concatenated_sequences.hpp +++ b/include/seqan3/alphabet/container/concatenated_sequences.hpp @@ -556,7 +556,9 @@ class concatenated_sequences reference operator[](size_type const i) { assert(i < size()); + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Warray-bounds) return data_values | views::slice(data_delimiters[i], data_delimiters[i + 1]); + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP } //!\copydoc operator[]() @@ -977,17 +979,11 @@ class concatenated_sequences auto placeholder = views::repeat_n(std::ranges::range_value_t{}, count * value_len) | std::views::common; // insert placeholder so the tail is moved once: -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstringop-overread" -# pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wstringop-overread, -Wstringop-overflow) data_values.insert(data_values.begin() + data_delimiters[pos_as_num], std::ranges::begin(placeholder), std::ranges::end(placeholder)); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP // assign the actual values to the placeholder: size_t i = data_delimiters[pos_as_num]; diff --git a/include/seqan3/core/platform.hpp b/include/seqan3/core/platform.hpp index 4ca71c4065..466951e135 100644 --- a/include/seqan3/core/platform.hpp +++ b/include/seqan3/core/platform.hpp @@ -227,14 +227,62 @@ static_assert(sdsl::sdsl_version_major == 3, "Only version 3 of the SDSL is supp # endif #endif -/*!\brief Workaround bogus memcpy errors in GCC > 12. (Wrestrict and Wstringop-overflow) - * \see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545 - */ #ifndef SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY # if SEQAN3_COMPILER_IS_GCC && (__GNUC__ >= 12) +// For checking whether workaround applies, e.g., in search_scheme_test # define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY 1 +// The goal is to create _Pragma("GCC disagnostic ignored \"-Wrestrict\"") +// The outer quotes are added by SEQAN3_PRAGMA, so we need SEQAN3_PRAGMA(GCC diagnostic ignored "-Wrestrict") +// SEQAN3_CONCAT_STRING(GCC diagnostic ignored, -Wrestrict) -> SEQAN3_PRAGMA(GCC diagnostic ignored "-Wrestrict") +# define SEQAN3_CONCAT_STRING(x, y) SEQAN3_PRAGMA(x #y) +# define SEQAN3_GCC_DIAGNOSTIC_IGNORE1(x, ...) \ + SEQAN3_PRAGMA(GCC diagnostic push) \ + SEQAN3_CONCAT_STRING(GCC diagnostic ignored, x) +# define SEQAN3_GCC_DIAGNOSTIC_IGNORE2(x, y) \ + SEQAN3_PRAGMA(GCC diagnostic push) \ + SEQAN3_CONCAT_STRING(GCC diagnostic ignored, x) \ + SEQAN3_CONCAT_STRING(GCC diagnostic ignored, y) +// A helper that enables SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START to take one or two arguments +// SEQAN3_GCC_DIAGNOSTIC_IGNORE(-Wrestict, 2, 1) -> SEQAN3_GCC_DIAGNOSTIC_IGNORE1(-Wrestict, 2) +// SEQAN3_GCC_DIAGNOSTIC_IGNORE(-Wrestict, -Warray-bounds, 2, 1) -> SEQAN3_GCC_DIAGNOSTIC_IGNORE2(-Wrestict, -Warray-bounds) +# define SEQAN3_GCC_DIAGNOSTIC_IGNORE(x, y, n, ...) SEQAN3_GCC_DIAGNOSTIC_IGNORE##n(x, y) +// SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict) -> SEQAN3_GCC_DIAGNOSTIC_IGNORE(-Wrestict, 2, 1) +// SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict, -Warray-bounds) -> SEQAN3_GCC_DIAGNOSTIC_IGNORE(-Wrestict, -Warray-bounds, 2, 1) +# define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(x, ...) SEQAN3_GCC_DIAGNOSTIC_IGNORE(x, ##__VA_ARGS__, 2, 1) +# define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP SEQAN3_PRAGMA(GCC diagnostic pop) # else +/*!\name Workaround for bogus memcopy/memmove warnings on GCC + * \{ + */ +//!\brief Indicates whether the workaround is active. `1` for GCC, `0` for other compilers. # define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY 0 +/*!\brief Denotes the start of a block where diagnostics are ignored. + * \details + * If SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY is 0, this macro has no effect. + * Otherwise, the macro takes one or two arguments and will expand to a preprocessor directive equivalent to: + * ### Input + * ```cpp + * // The macro accepts one or two arguments. + * SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict, -Warray-bounds) + * ``` + * ### Output + * ```cpp + * #pragma GCC diagnostic push + * #pragma GCC diagnostic ignored "-Wrestrict" + * #pragma GCC diagnostic ignored "-Warray-bounds" + * ``` + */ +# define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(...) +/*!\brief Denotes the end of a block where diagnostics are ignored. + * \details + * If SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY is 0, this macro has no effect. + * Otherwise, the macro takes will expand to a preprocessor directive equivalent to: + * ```cpp + * #pragma GCC diagnostic pop + * ``` + */ +# define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP +//!\} # endif #endif diff --git a/include/seqan3/utility/container/small_vector.hpp b/include/seqan3/utility/container/small_vector.hpp index fb51452cd4..7386b509ac 100644 --- a/include/seqan3/utility/container/small_vector.hpp +++ b/include/seqan3/utility/container/small_vector.hpp @@ -735,14 +735,9 @@ class small_vector for (size_type i = sz + length - 1; i > pos_as_num + length - 1; --i) data_[i] = data_[i - length]; -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wstringop-overflow) std::ranges::copy(begin_it, end_it, &data_[pos_as_num]); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP sz += length; return begin() + pos_as_num; } diff --git a/test/unit/alphabet/container/container_concept_test.cpp b/test/unit/alphabet/container/container_concept_test.cpp index 48b36569c3..bc6b08d53b 100644 --- a/test/unit/alphabet/container/container_concept_test.cpp +++ b/test/unit/alphabet/container/container_concept_test.cpp @@ -64,10 +64,7 @@ TEST(container, sequence_container_former_travis_bug) s.insert(0, 1, 'E'); EXPECT_EQ("Exmplr", s); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wrestrict" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict) // insert(size_type index, const char* s) s.insert(2, "e"); EXPECT_EQ("Exemplr", s); @@ -75,9 +72,7 @@ TEST(container, sequence_container_former_travis_bug) // insert(size_type index, string const& str) s.insert(6, "a"s); EXPECT_EQ("Exemplar", s); -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP // insert(size_type index, string const& str, size_type index_str, size_type count) s.insert(8, " is an example string."s, 0, 14); @@ -99,17 +94,12 @@ TEST(container, sequence_container_former_travis_bug) EXPECT_EQ("Exemplar is an:== example string", s); } -# if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wrestrict" -# endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict) // insert(const_iterator pos, std::initializer_list) s.insert(s.begin() + s.find_first_of('g') + 1, {'.'}); EXPECT_EQ("Exemplar is an:== example string.", s); -# if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -# endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -#else // ^^^ workaround / no workaround vvv + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP +#else // ^^^ workaround / no workaround vvv // insert(const_iterator pos, char ch) s.insert(s.cbegin() + s.find_first_of('n') + 1, ':'); EXPECT_EQ("Exemplar is an: example", s); @@ -126,16 +116,11 @@ TEST(container, sequence_container_former_travis_bug) } // insert(const_iterator pos, std::initializer_list) -# if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wrestrict" -# endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wrestrict) s.insert(s.cbegin() + s.find_first_of('g') + 1, {'.'}); EXPECT_EQ("Exemplar is an:== example string.", s); -# if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -# endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -#endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP +#endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI } TEST(container, sequence_container) diff --git a/test/unit/alphabet/container/debug_stream_container_of_container_test.cpp b/test/unit/alphabet/container/debug_stream_container_of_container_test.cpp index 222a8c3dc6..e495d4d85c 100644 --- a/test/unit/alphabet/container/debug_stream_container_of_container_test.cpp +++ b/test/unit/alphabet/container/debug_stream_container_of_container_test.cpp @@ -25,15 +25,9 @@ TYPED_TEST_SUITE(debug_stream_test, container_of_container_types, ); TYPED_TEST(debug_stream_test, container_of_container) { -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Warray-bounds" -# pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Warray-bounds, -Wstringop-overflow) TypeParam t1{"ACGT"_dna4, "ACGT"_dna4, "GAGGA"_dna4}; -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY -# pragma GCC diagnostic pop -#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY + SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP std::ostringstream o; seqan3::debug_stream_type my_stream{o}; diff --git a/test/unit/search/search_scheme_test.cpp b/test/unit/search/search_scheme_test.cpp index 387fde7311..0f2f1e5d21 100644 --- a/test/unit/search/search_scheme_test.cpp +++ b/test/unit/search/search_scheme_test.cpp @@ -11,7 +11,7 @@ #include "helper_search_scheme.hpp" -#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY +#ifdef SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY using integral_t = uint16_t; #else using integral_t = uint8_t;