| # Copyright 2026 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| # DO NOT EDIT! This file is generated by generate_fuchsia_patch.py. |
| # |
| # To make changes, update and run ./generate_fuchsia_patch.py. |
| |
| # Patch the fit::function implementation for use in Pigweed: |
| # |
| # - Use PW_ASSERT instead of __builtin_abort. |
| # - Temporarily disable sanitizers when invoking a function for b/241567321. |
| # |
| diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h |
| --- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h |
| +++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h |
| @@ -20,6 +20,8 @@ |
| #include <utility> |
| |
| #include "../nullable.h" |
| +#include "pw_assert/assert.h" |
| +#include "pw_preprocessor/compiler.h" |
| |
| namespace fit { |
| namespace internal { |
| @@ -90,7 +92,7 @@ inline const void* unshared_target_type_id(void* /*bits*/, const void* impl_ops) |
| // elsewhere in the header as an inline variable. |
| template <typename Unused = void> |
| struct null_target { |
| - static void invoke(void* /*bits*/) { __builtin_abort(); } |
| + static void invoke(void* /*bits*/) { PW_ASSERT(false); } |
| |
| static const target_ops<void> ops; |
| |
| @@ -542,7 +544,7 @@ class function_base<inline_target_size, require_inline, Result(Args...), Allocat |
| template <typename SharedFunction> |
| void copy_shared_target_to(SharedFunction& copy) { |
| copy.destroy_target(); |
| - assert(base::ops() == &shared_target_type<SharedFunction>::ops); |
| + PW_ASSERT(base::ops() == &shared_target_type<SharedFunction>::ops); |
| shared_target_type<SharedFunction>::copy_shared_ptr(base::bits(), copy.bits()); |
| copy.set_ops(base::ops()); |
| } |
| @@ -572,7 +574,7 @@ class function_base<inline_target_size, require_inline, Result(Args...), Allocat |
| void check_target_type() const { |
| if (target_type<Callable>::ops.target_type_id(nullptr, &target_type<Callable>::ops) != |
| base::target_type_id()) { |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| } |
| }; |
| diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h |
| --- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h |
| +++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h |
| @@ -14,6 +14,11 @@ |
| #include <type_traits> |
| #include <utility> |
| |
| +#include "pw_preprocessor/compiler.h" |
| + |
| +PW_MODIFY_DIAGNOSTICS_PUSH(); |
| +PW_MODIFY_DIAGNOSTIC_CLANG(ignored, "-Wshadow-field-in-constructor"); |
| + |
| namespace fit { |
| |
| // Forward declarations. |
| @@ -458,4 +463,6 @@ using storage = storage_type<storage_class_trait<E, Ts...>, E, Ts...>; |
| } // namespace internal |
| } // namespace fit |
| |
| +PW_MODIFY_DIAGNOSTICS_POP(); |
| + |
| #endif // LIB_FIT_INTERNAL_RESULT_H_ |
| diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h |
| --- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h |
| +++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h |
| @@ -10,6 +10,8 @@ |
| #include <type_traits> |
| #include <utility> |
| |
| +#include "pw_assert/assert.h" |
| + |
| namespace fit { |
| |
| // Determines whether a type can be compared with nullptr. |
| @@ -132,25 +134,25 @@ class nullable<T, true> final { |
| if (has_value()) { |
| return value_; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const T& value() const& { |
| if (has_value()) { |
| return value_; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr T&& value() && { |
| if (has_value()) { |
| return std::move(value_); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const T&& value() const&& { |
| if (has_value()) { |
| return std::move(value_); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| template <typename U = T> |
| diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h |
| --- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h |
| +++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h |
| @@ -55,6 +55,12 @@ |
| // // fit::result with a different "success" vluae type (or |
| // // fit::result<E>). |
| |
| +#include "pw_assert/assert.h" |
| +#include "pw_preprocessor/compiler.h" |
| + |
| +PW_MODIFY_DIAGNOSTICS_PUSH(); |
| +PW_MODIFY_DIAGNOSTIC_CLANG(ignored, "-Wshadow-field-in-constructor"); |
| + |
| namespace fit { |
| |
| // Convenience type to indicate failure without elaboration. |
| @@ -282,25 +288,25 @@ class [[nodiscard]] result<E, T> { |
| if (is_error()) { |
| return storage_.error_or_value.error; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const E& error_value() const& { |
| if (is_error()) { |
| return storage_.error_or_value.error; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr E&& error_value() && { |
| if (is_error()) { |
| return std::move(storage_.error_or_value.error); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const E&& error_value() const&& { |
| if (is_error()) { |
| return std::move(storage_.error_or_value.error); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Moves the underlying error and returns it as an instance of fit::error, simplifying |
| @@ -311,7 +317,7 @@ class [[nodiscard]] result<E, T> { |
| if (is_error()) { |
| return error<E>(std::move(storage_.error_or_value.error)); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Accessors for the underlying value. |
| @@ -321,25 +327,25 @@ class [[nodiscard]] result<E, T> { |
| if (is_ok()) { |
| return storage_.error_or_value.value; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const T& value() const& { |
| if (is_ok()) { |
| return storage_.error_or_value.value; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr T&& value() && { |
| if (is_ok()) { |
| return std::move(storage_.error_or_value.value); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const T&& value() const&& { |
| if (is_ok()) { |
| return std::move(storage_.error_or_value.value); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Moves the underlying value and returns it as an instance of fit::success, simplifying |
| @@ -350,7 +356,7 @@ class [[nodiscard]] result<E, T> { |
| if (is_ok()) { |
| return success<T>(std::move(storage_.error_or_value.value)); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Contingent accessors for the underlying value. |
| @@ -379,13 +385,13 @@ class [[nodiscard]] result<E, T> { |
| if (is_ok()) { |
| return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr decltype(auto) operator->() const { |
| if (is_ok()) { |
| return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Accessors for the underlying value. This is a syntax sugar for value(). |
| @@ -408,7 +414,7 @@ class [[nodiscard]] result<E, T> { |
| storage_.error_or_value.error += std::move(error.value_); |
| return *this; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Maps a result<E, T> to a result<E2, T> by transforming the error through |
| @@ -519,25 +525,25 @@ class [[nodiscard]] result<E> { |
| if (is_error()) { |
| return storage_.error_or_value.error; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const E& error_value() const& { |
| if (is_error()) { |
| return storage_.error_or_value.error; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr E&& error_value() && { |
| if (is_error()) { |
| return std::move(storage_.error_or_value.error); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| constexpr const E&& error_value() const&& { |
| if (is_error()) { |
| return std::move(storage_.error_or_value.error); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Moves the underlying error and returns it as an instance of fit::error, simplifying |
| @@ -548,7 +554,7 @@ class [[nodiscard]] result<E> { |
| if (is_error()) { |
| return error<E>(std::move(storage_.error_or_value.error)); |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Augments the error value of the result with the given value. The operator E::operator+=(F) must |
| @@ -562,7 +568,7 @@ class [[nodiscard]] result<E> { |
| storage_.error_or_value.error += std::move(error.value_); |
| return *this; |
| } |
| - __builtin_abort(); |
| + PW_ASSERT(false); |
| } |
| |
| // Maps a result<E, T> to a result<E2, T> by transforming the error through |
| @@ -797,4 +803,6 @@ constexpr bool operator>=(const T& lhs, const result<F, U>& rhs) { |
| |
| } // namespace fit |
| |
| +PW_MODIFY_DIAGNOSTICS_POP(); |
| + |
| #endif // LIB_FIT_RESULT_H_ |
| diff --git a/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc b/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc |
| --- a/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc |
| +++ b/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc |
| @@ -4,7 +4,6 @@ |
| |
| #include <lib/fit/function.h> |
| #include <lib/stdcompat/bit.h> |
| -#include <zircon/compiler.h> |
| |
| #include <algorithm> |
| #include <array> |
| @@ -15,6 +14,8 @@ |
| |
| #include <zxtest/zxtest.h> |
| |
| +#include "pw_polyfill/language_feature_macros.h" |
| + |
| namespace { |
| |
| using ::std::size_t; |
| @@ -54,8 +55,7 @@ struct EmptyFunction<R(Args...)> { |
| R operator()(Args... args) const { return fptr(args...); } |
| bool operator==(decltype(nullptr)) const { return true; } |
| |
| - R(*fptr) |
| - (Args...) = nullptr; |
| + R (*fptr)(Args...) = nullptr; |
| }; |
| |
| struct alignas(4 * alignof(void*)) LargeAlignedCallable { |
| @@ -1029,8 +1029,8 @@ TEST(FunctionTests, callback_with_custom_allocator) { |
| EXPECT_EQ(1, cbheapdestroy); |
| } |
| |
| -__CONSTINIT const fit::function<void()> kDefaultConstructed; |
| -__CONSTINIT const fit::function<void()> kNullptrConstructed(nullptr); |
| +PW_CONSTINIT const fit::function<void()> kDefaultConstructed; |
| +PW_CONSTINIT const fit::function<void()> kNullptrConstructed(nullptr); |
| |
| TEST(FunctionTests, null_constructors_are_constexpr) { |
| EXPECT_EQ(kDefaultConstructed, nullptr); |