1# Copyright 2024 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15# DO NOT EDIT! This file is generated by generate_fuchsia_patch.py. 16# 17# To make changes, update and run ./generate_fuchsia_patch.py. 18 19# Patch the fit::function implementation for use in Pigweed: 20# 21# - Use PW_ASSERT instead of __builtin_abort. 22# - Temporarily disable sanitizers when invoking a function for b/241567321. 23# 24diff --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 25--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h 26+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h 27@@ -18,6 +18,8 @@ 28 #include <utility> 29 30 #include "../nullable.h" 31+#include "pw_assert/assert.h" 32+#include "pw_preprocessor/compiler.h" 33 34 namespace fit { 35 namespace internal { 36@@ -88,7 +90,7 @@ inline const void* unshared_target_type_id(void* /*bits*/, const void* impl_ops) 37 // elsewhere in the header as an inline variable. 38 template <typename Unused = void> 39 struct null_target { 40- static void invoke(void* /*bits*/) { __builtin_abort(); } 41+ static void invoke(void* /*bits*/) { PW_ASSERT(false); } 42 43 static const target_ops<void> ops; 44 45@@ -510,7 +512,8 @@ class function_base<inline_target_size, require_inline, Result(Args...), Allocat 46 // Note that fit::callback will release the target immediately after 47 // invoke() (also affecting any share()d copies). 48 // Aborts if the function's target is empty. 49- Result invoke(Args... args) const { 50+ // TODO: b/241567321 - Remove "no sanitize" after pw_protobuf is fixed. 51+ Result invoke(Args... args) const PW_NO_SANITIZE("function") { 52 // Down cast the ops to the derived type that this function was instantiated 53 // with, which includes the invoke function. 54 // 55@@ -540,7 +543,7 @@ class function_base<inline_target_size, require_inline, Result(Args...), Allocat 56 template <typename SharedFunction> 57 void copy_shared_target_to(SharedFunction& copy) { 58 copy.destroy_target(); 59- assert(base::ops() == &shared_target_type<SharedFunction>::ops); 60+ PW_ASSERT(base::ops() == &shared_target_type<SharedFunction>::ops); 61 shared_target_type<SharedFunction>::copy_shared_ptr(base::bits(), copy.bits()); 62 copy.set_ops(base::ops()); 63 } 64@@ -570,7 +573,7 @@ class function_base<inline_target_size, require_inline, Result(Args...), Allocat 65 void check_target_type() const { 66 if (target_type<Callable>::ops.target_type_id(nullptr, &target_type<Callable>::ops) != 67 base::target_type_id()) { 68- __builtin_abort(); 69+ PW_ASSERT(false); 70 } 71 } 72 }; 73diff --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 74--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h 75+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h 76@@ -14,6 +14,11 @@ 77 #include <type_traits> 78 #include <utility> 79 80+#include "pw_preprocessor/compiler.h" 81+ 82+PW_MODIFY_DIAGNOSTICS_PUSH(); 83+PW_MODIFY_DIAGNOSTIC_CLANG(ignored, "-Wshadow-field-in-constructor"); 84+ 85 namespace fit { 86 87 // Forward declarations. 88@@ -60,7 +65,7 @@ struct template_matcher { 89 }; 90 91 template <typename T, template <typename...> class U, typename = bool> 92-struct is_match : decltype(template_matcher<U>::match(std::declval<T>())) {}; 93+struct is_match : decltype(template_matcher<U>::match(std::declval<T>())){}; 94 95 template <typename T, template <typename...> class U> 96 struct is_match<T, U, requires_conditions<std::is_void<T>>> : std::false_type {}; 97@@ -441,4 +446,6 @@ using storage = storage_type<storage_class_trait<E, Ts...>, E, Ts...>; 98 } // namespace internal 99 } // namespace fit 100 101+PW_MODIFY_DIAGNOSTICS_POP(); 102+ 103 #endif // LIB_FIT_INTERNAL_RESULT_H_ 104diff --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 105--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h 106+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h 107@@ -11,6 +11,8 @@ 108 #include <type_traits> 109 #include <utility> 110 111+#include "pw_assert/assert.h" 112+ 113 namespace fit { 114 115 // Determines whether a type can be compared with nullptr. 116@@ -130,25 +132,25 @@ class nullable<T, true> final { 117 if (has_value()) { 118 return value_; 119 } 120- __builtin_abort(); 121+ PW_ASSERT(false); 122 } 123 constexpr const T& value() const& { 124 if (has_value()) { 125 return value_; 126 } 127- __builtin_abort(); 128+ PW_ASSERT(false); 129 } 130 constexpr T&& value() && { 131 if (has_value()) { 132 return std::move(value_); 133 } 134- __builtin_abort(); 135+ PW_ASSERT(false); 136 } 137 constexpr const T&& value() const&& { 138 if (has_value()) { 139 return std::move(value_); 140 } 141- __builtin_abort(); 142+ PW_ASSERT(false); 143 } 144 145 template <typename U = T> 146diff --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 147--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h 148+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h 149@@ -55,6 +55,12 @@ 150 // // fit::result with a different "success" vluae type (or 151 // // fit::result<E>). 152 153+#include "pw_assert/assert.h" 154+#include "pw_preprocessor/compiler.h" 155+ 156+PW_MODIFY_DIAGNOSTICS_PUSH(); 157+PW_MODIFY_DIAGNOSTIC_CLANG(ignored, "-Wshadow-field-in-constructor"); 158+ 159 namespace fit { 160 161 // Convenience type to indicate failure without elaboration. 162@@ -286,25 +292,25 @@ class [[nodiscard]] result<E, T> { 163 if (is_error()) { 164 return storage_.error_or_value.error; 165 } 166- __builtin_abort(); 167+ PW_ASSERT(false); 168 } 169 constexpr const E& error_value() const& { 170 if (is_error()) { 171 return storage_.error_or_value.error; 172 } 173- __builtin_abort(); 174+ PW_ASSERT(false); 175 } 176 constexpr E&& error_value() && { 177 if (is_error()) { 178 return std::move(storage_.error_or_value.error); 179 } 180- __builtin_abort(); 181+ PW_ASSERT(false); 182 } 183 constexpr const E&& error_value() const&& { 184 if (is_error()) { 185 return std::move(storage_.error_or_value.error); 186 } 187- __builtin_abort(); 188+ PW_ASSERT(false); 189 } 190 191 // Moves the underlying error and returns it as an instance of fit::error, simplifying 192@@ -315,7 +321,7 @@ class [[nodiscard]] result<E, T> { 193 if (is_error()) { 194 return error<E>(std::move(storage_.error_or_value.error)); 195 } 196- __builtin_abort(); 197+ PW_ASSERT(false); 198 } 199 200 // Accessors for the underlying value. 201@@ -325,25 +331,25 @@ class [[nodiscard]] result<E, T> { 202 if (is_ok()) { 203 return storage_.error_or_value.value; 204 } 205- __builtin_abort(); 206+ PW_ASSERT(false); 207 } 208 constexpr const T& value() const& { 209 if (is_ok()) { 210 return storage_.error_or_value.value; 211 } 212- __builtin_abort(); 213+ PW_ASSERT(false); 214 } 215 constexpr T&& value() && { 216 if (is_ok()) { 217 return std::move(storage_.error_or_value.value); 218 } 219- __builtin_abort(); 220+ PW_ASSERT(false); 221 } 222 constexpr const T&& value() const&& { 223 if (is_ok()) { 224 return std::move(storage_.error_or_value.value); 225 } 226- __builtin_abort(); 227+ PW_ASSERT(false); 228 } 229 230 // Moves the underlying value and returns it as an instance of fit::success, simplifying 231@@ -354,7 +360,7 @@ class [[nodiscard]] result<E, T> { 232 if (is_ok()) { 233 return success<T>(std::move(storage_.error_or_value.value)); 234 } 235- __builtin_abort(); 236+ PW_ASSERT(false); 237 } 238 239 // Contingent accessors for the underlying value. 240@@ -383,13 +389,13 @@ class [[nodiscard]] result<E, T> { 241 if (is_ok()) { 242 return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); 243 } 244- __builtin_abort(); 245+ PW_ASSERT(false); 246 } 247 constexpr decltype(auto) operator->() const { 248 if (is_ok()) { 249 return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); 250 } 251- __builtin_abort(); 252+ PW_ASSERT(false); 253 } 254 255 // Accessors for the underlying value. This is a syntax sugar for value(). 256@@ -412,7 +418,7 @@ class [[nodiscard]] result<E, T> { 257 storage_.error_or_value.error += std::move(error.value_); 258 return *this; 259 } 260- __builtin_abort(); 261+ PW_ASSERT(false); 262 } 263 264 // Maps a result<E, T> to a result<E2, T> by transforming the error through 265@@ -523,25 +529,25 @@ class [[nodiscard]] result<E> { 266 if (is_error()) { 267 return storage_.error_or_value.error; 268 } 269- __builtin_abort(); 270+ PW_ASSERT(false); 271 } 272 constexpr const E& error_value() const& { 273 if (is_error()) { 274 return storage_.error_or_value.error; 275 } 276- __builtin_abort(); 277+ PW_ASSERT(false); 278 } 279 constexpr E&& error_value() && { 280 if (is_error()) { 281 return std::move(storage_.error_or_value.error); 282 } 283- __builtin_abort(); 284+ PW_ASSERT(false); 285 } 286 constexpr const E&& error_value() const&& { 287 if (is_error()) { 288 return std::move(storage_.error_or_value.error); 289 } 290- __builtin_abort(); 291+ PW_ASSERT(false); 292 } 293 294 // Moves the underlying error and returns it as an instance of fit::error, simplifying 295@@ -552,7 +558,7 @@ class [[nodiscard]] result<E> { 296 if (is_error()) { 297 return error<E>(std::move(storage_.error_or_value.error)); 298 } 299- __builtin_abort(); 300+ PW_ASSERT(false); 301 } 302 303 // Augments the error value of the result with the given value. The operator E::operator+=(F) must 304@@ -566,7 +572,7 @@ class [[nodiscard]] result<E> { 305 storage_.error_or_value.error += std::move(error.value_); 306 return *this; 307 } 308- __builtin_abort(); 309+ PW_ASSERT(false); 310 } 311 312 // Maps a result<E, T> to a result<E2, T> by transforming the error through 313@@ -801,4 +807,6 @@ constexpr bool operator>=(const T& lhs, const result<F, U>& rhs) { 314 315 } // namespace fit 316 317+PW_MODIFY_DIAGNOSTICS_POP(); 318+ 319 #endif // LIB_FIT_RESULT_H_ 320diff --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 321--- a/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc 322+++ b/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc 323@@ -4,7 +4,6 @@ 324 325 #include <lib/fit/function.h> 326 #include <lib/stdcompat/bit.h> 327-#include <zircon/compiler.h> 328 329 #include <algorithm> 330 #include <array> 331@@ -15,6 +14,8 @@ 332 333 #include <zxtest/zxtest.h> 334 335+#include "pw_polyfill/language_feature_macros.h" 336+ 337 namespace { 338 339 using ::std::size_t; 340@@ -1029,8 +1030,8 @@ TEST(FunctionTests, callback_with_custom_allocator) { 341 EXPECT_EQ(1, cbheapdestroy); 342 } 343 344-__CONSTINIT const fit::function<void()> kDefaultConstructed; 345-__CONSTINIT const fit::function<void()> kNullptrConstructed(nullptr); 346+PW_CONSTINIT const fit::function<void()> kDefaultConstructed; 347+PW_CONSTINIT const fit::function<void()> kNullptrConstructed(nullptr); 348 349 TEST(FunctionTests, null_constructors_are_constexpr) { 350 EXPECT_EQ(kDefaultConstructed, nullptr); 351