Fixes for GCC 10 compatibility
- pw_kvs: Remove use of std::enable_if that wasn't working property.
- pw_result, pw_rpc: Disable spurious GCC 10 warnings.
- pw_string: Size report code that is never executed was using the same
pointer for snprintf input and output, which is not legal. This caused
-Wrestrict warnings. Update the size report code to avoid this.
- Add the -pthread flag in GCC host builds to support building
pw_thread.
- pw_tokenizer: For host builds, insert the tokenizer sections after
.debug_info instead of .strtab, since inserting after .strtab does not
work for GCC.
Change-Id: Ib141a102ed50eb639c8d0bcb236572b3dc142ec1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/40620
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_kvs/public/pw_kvs/checksum.h b/pw_kvs/public/pw_kvs/checksum.h
index 6a42e00..7624e39 100644
--- a/pw_kvs/public/pw_kvs/checksum.h
+++ b/pw_kvs/public/pw_kvs/checksum.h
@@ -95,7 +95,7 @@
protected:
constexpr AlignedChecksum(std::span<const std::byte> state)
: ChecksumAlgorithm(state),
- output_(this),
+ output_(*this),
writer_(kAlignmentBytes, output_) {}
~AlignedChecksum() = default;
@@ -112,10 +112,20 @@
virtual void FinalizeAligned() = 0;
- OutputToMethod<void (AlignedChecksum<kAlignmentBytes, kBufferSize>::*)(
- std::span<const std::byte>),
- &AlignedChecksum::UpdateAligned>
- output_;
+ class CallUpdateAligned final : public Output {
+ public:
+ constexpr CallUpdateAligned(AlignedChecksum& object) : object_(object) {}
+
+ private:
+ StatusWithSize DoWrite(std::span<const std::byte> data) override {
+ object_.UpdateAligned(data);
+ return StatusWithSize(data.size());
+ }
+
+ AlignedChecksum& object_;
+ };
+
+ CallUpdateAligned output_;
AlignedWriterBuffer<kBufferSize> writer_;
};
diff --git a/pw_kvs/public/pw_kvs/io.h b/pw_kvs/public/pw_kvs/io.h
index 193427c..58fe24d 100644
--- a/pw_kvs/public/pw_kvs/io.h
+++ b/pw_kvs/public/pw_kvs/io.h
@@ -71,43 +71,6 @@
virtual StatusWithSize DoRead(std::span<std::byte> data) = 0;
};
-// Output adapter that calls a method on a class with a std::span of bytes. If
-// the method returns void instead of the expected Status, Write always returns
-// OkStatus().
-template <typename T, T kMethod>
-class OutputToMethod final : public Output {
- using Class = typename internal::FunctionTraits<decltype(kMethod)>::Class;
-
- public:
- constexpr OutputToMethod(Class* object) : object_(*object) {}
-
- private:
- using Return = typename internal::FunctionTraits<decltype(kMethod)>::Return;
- template <T kMethodImpl = kMethod>
- typename std::enable_if<std::is_void<typename internal::FunctionTraits<
- decltype(kMethodImpl)>::Return>::value,
- StatusWithSize>::type
- DoWriteImpl(std::span<const std::byte> data) {
- (object_.*kMethod)(data);
- return StatusWithSize(data.size());
- }
-
- template <T kMethodImpl = kMethod>
- typename std::enable_if<!std::is_void<typename internal::FunctionTraits<
- decltype(kMethodImpl)>::Return>::value,
- StatusWithSize>::type
- DoWriteImpl(std::span<const std::byte> data) {
- return (object_.*kMethod)(data);
- }
-
- StatusWithSize DoWrite(std::span<const std::byte> data) override {
- return DoWriteImpl(data);
- }
-
- private:
- Class& object_;
-};
-
// Output adapter that calls a free function.
class OutputToFunction final : public Output {
public:
diff --git a/pw_result/public/pw_result/result.h b/pw_result/public/pw_result/result.h
index a55c2b4..ba78e8a 100644
--- a/pw_result/public/pw_result/result.h
+++ b/pw_result/public/pw_result/result.h
@@ -68,7 +68,11 @@
template <typename U>
constexpr T value_or(U&& default_value) const& {
if (ok()) {
+ PW_MODIFY_DIAGNOSTICS_PUSH();
+ // GCC 10 emits -Wmaybe-uninitialized warnings about value_.
+ PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wmaybe-uninitialized");
return value_;
+ PW_MODIFY_DIAGNOSTICS_POP();
}
return std::forward<U>(default_value);
}
diff --git a/pw_rpc/public/pw_rpc/service.h b/pw_rpc/public/pw_rpc/service.h
index 3884d02..4e1a1a0 100644
--- a/pw_rpc/public/pw_rpc/service.h
+++ b/pw_rpc/public/pw_rpc/service.h
@@ -18,6 +18,7 @@
#include <span>
#include "pw_containers/intrusive_list.h"
+#include "pw_preprocessor/compiler.h"
#include "pw_rpc/internal/method.h"
#include "pw_rpc/internal/method_union.h"
@@ -40,7 +41,11 @@
methods_(methods.data()),
method_size_(sizeof(T)),
method_count_(static_cast<uint16_t>(kMethodCount)) {
+ PW_MODIFY_DIAGNOSTICS_PUSH();
+ // GCC 10 emits spurious -Wtype-limits warnings for the static_assert.
+ PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wtype-limits");
static_assert(kMethodCount <= std::numeric_limits<uint16_t>::max());
+ PW_MODIFY_DIAGNOSTICS_POP();
}
// For use by tests with only one method.
diff --git a/pw_string/size_report/format_many_without_error_handling.cc b/pw_string/size_report/format_many_without_error_handling.cc
index 357fc2a..7a5ab2d 100644
--- a/pw_string/size_report/format_many_without_error_handling.cc
+++ b/pw_string/size_report/format_many_without_error_handling.cc
@@ -38,18 +38,22 @@
namespace pw::string {
-char* volatile get_buffer;
+char buffer_1[128];
+char buffer_2[128];
+
+char* volatile get_buffer_1 = buffer_1;
+char* volatile get_buffer_2 = buffer_2;
volatile unsigned get_size;
void OutputStringsToBuffer() {
#if USE_FORMAT
- auto buffer = std::span(get_buffer, get_size);
+ auto buffer = std::span(get_buffer_1, get_size);
#else
- char* buffer = get_buffer;
+ char* buffer = get_buffer_1;
unsigned buffer_size = get_size;
#endif // USE_FORMAT
- const char* string = get_buffer;
+ const char* string = get_buffer_2;
unsigned value = get_size;
FORMAT_CASE("The quick brown");
diff --git a/pw_string/size_report/format_multiple.cc b/pw_string/size_report/format_multiple.cc
index b27df5a..7f516cb 100644
--- a/pw_string/size_report/format_multiple.cc
+++ b/pw_string/size_report/format_multiple.cc
@@ -82,12 +82,16 @@
namespace pw::string {
-char* volatile get_buffer;
+char buffer_1[128];
+char buffer_2[128];
+
+char* volatile get_buffer_1 = buffer_1;
+char* volatile get_buffer_2 = buffer_2;
volatile unsigned get_size;
unsigned OutputStringsToBuffer() {
- char* buffer = get_buffer;
- const char* string = get_buffer;
+ char* buffer = get_buffer_1;
+ const char* string = get_buffer_2;
unsigned buffer_size = get_size;
unsigned string_size = 0;
diff --git a/pw_string/size_report/format_single.cc b/pw_string/size_report/format_single.cc
index 94afe76..6afee11 100644
--- a/pw_string/size_report/format_single.cc
+++ b/pw_string/size_report/format_single.cc
@@ -31,18 +31,22 @@
namespace pw::string {
-char* volatile get_buffer;
+char buffer_1[128];
+char buffer_2[128];
+
+char* volatile get_buffer_1 = buffer_1;
+char* volatile get_buffer_2 = buffer_2;
volatile unsigned get_size;
unsigned OutputStringsToBuffer() {
- char* buffer = get_buffer;
+ char* buffer = get_buffer_1;
unsigned buffer_size = get_size;
#if USE_FORMAT
// The code for using pw::string::Format is much simpler and safer.
return Format(std::span(buffer, buffer_size),
"hello %s %d",
- get_buffer,
+ get_buffer_2,
get_size)
.size();
#else // std::snprintf
@@ -51,7 +55,7 @@
}
int result =
- std::snprintf(buffer, buffer_size, "hello %s %d", get_buffer, get_size);
+ std::snprintf(buffer, buffer_size, "hello %s %d", get_buffer_2, get_size);
if (result < 0) {
buffer[0] = '\0';
return 0;
diff --git a/pw_tokenizer/add_tokenizer_sections_to_default_script.ld b/pw_tokenizer/add_tokenizer_sections_to_default_script.ld
index 41cc0c1..56890b0 100644
--- a/pw_tokenizer/add_tokenizer_sections_to_default_script.ld
+++ b/pw_tokenizer/add_tokenizer_sections_to_default_script.ld
@@ -20,6 +20,6 @@
* The INSERT directive instructs the linker to append the directives in this
* script to the default linker script, rather than replace the default with
* this script. It doesn't matter where the tokenizer sections are inserted, so
- * insert them after the standard .strtab section.
+ * insert them after the .debug_info section, which both clang and GCC use.
*/
-INSERT AFTER .strtab
+INSERT AFTER .debug_info
diff --git a/pw_toolchain/host_gcc/BUILD.gn b/pw_toolchain/host_gcc/BUILD.gn
index e0cdbf1..e073821 100644
--- a/pw_toolchain/host_gcc/BUILD.gn
+++ b/pw_toolchain/host_gcc/BUILD.gn
@@ -40,3 +40,9 @@
cflags = [ "-D__USE_MINGW_ANSI_STDIO=1" ]
}
}
+
+# GCC needs the -pthread option to support multithreading. This must be
+# specified to build e.g. pw_thread_stl.
+config("threading_support") {
+ ldflags = [ "-pthread" ]
+}
diff --git a/targets/host/target_toolchains.gni b/targets/host/target_toolchains.gni
index 9a7a733..07b769a 100644
--- a/targets/host/target_toolchains.gni
+++ b/targets/host/target_toolchains.gni
@@ -112,7 +112,10 @@
"$dir_pw_build:extra_strict_warnings",
"$dir_pw_build:clang_thread_safety_warnings",
]
-_gcc_default_configs = [ "$dir_pw_build:extra_strict_warnings" ]
+_gcc_default_configs = [
+ "$dir_pw_build:extra_strict_warnings",
+ "$dir_pw_toolchain/host_gcc:threading_support",
+]
pw_target_toolchain_host = {
_excluded_members = [