1# Copyright 2023 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# Patch the fit::function implementation for use in Pigweed: 16# 17# - Use PW_ASSERT instead of __builtin_abort. 18# - Temporarily disable sanitizers when invoking a function for b/241567321. 19# 20diff --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 21--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h 22+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/function.h 23@@ -18,6 +18,8 @@ 24 #include <utility> 25 26 #include "../nullable.h" 27+#include "pw_assert/assert.h" 28+#include "pw_preprocessor/compiler.h" 29 30 namespace fit { 31 namespace internal { 32@@ -87,7 +89,7 @@ inline const void* unshared_target_type_id(void* /*bits*/, const void* impl_ops) 33 // elsewhere in the header as an inline variable. 34 template <typename Unused = void> 35 struct null_target { 36- static void invoke(void* /*bits*/) { __builtin_abort(); } 37+ static void invoke(void* /*bits*/) { PW_ASSERT(false); } 38 39 static const target_ops<void> ops; 40 41@@ -493,7 +495,8 @@ class function_base<inline_target_size, require_inline, Result(Args...)> 42 // Note that fit::callback will release the target immediately after 43 // invoke() (also affecting any share()d copies). 44 // Aborts if the function's target is empty. 45- Result invoke(Args... args) const { 46+ // TODO(b/241567321): Remove "no sanitize" after pw_protobuf is fixed. 47+ Result invoke(Args... args) const PW_NO_SANITIZE("function") { 48 // Down cast the ops to the derived type that this function was instantiated 49 // with, which includes the invoke function. 50 // 51@@ -523,7 +526,7 @@ class function_base<inline_target_size, require_inline, Result(Args...)> 52 template <typename SharedFunction> 53 void copy_shared_target_to(SharedFunction& copy) { 54 copy.destroy_target(); 55- assert(base::ops() == &shared_target_type<SharedFunction>::ops); 56+ PW_ASSERT(base::ops() == &shared_target_type<SharedFunction>::ops); 57 shared_target_type<SharedFunction>::copy_shared_ptr(base::bits(), copy.bits()); 58 copy.set_ops(base::ops()); 59 } 60@@ -553,7 +556,7 @@ class function_base<inline_target_size, require_inline, Result(Args...)> 61 void check_target_type() const { 62 if (target_type<Callable>::ops.target_type_id(nullptr, &target_type<Callable>::ops) != 63 base::target_type_id()) { 64- __builtin_abort(); 65+ PW_ASSERT(false); 66 } 67 } 68 }; 69diff --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 70--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h 71+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/nullable.h 72@@ -11,6 +11,8 @@ 73 #include <type_traits> 74 #include <utility> 75 76+#include "pw_assert/assert.h" 77+ 78 namespace fit { 79 80 // Determines whether a type can be compared with nullptr. 81@@ -130,28 +132,28 @@ class nullable<T, true> final { 82 if (has_value()) { 83 return value_; 84 } else { 85- __builtin_abort(); 86+ PW_ASSERT(false); 87 } 88 } 89 constexpr const T& value() const& { 90 if (has_value()) { 91 return value_; 92 } else { 93- __builtin_abort(); 94+ PW_ASSERT(false); 95 } 96 } 97 constexpr T&& value() && { 98 if (has_value()) { 99 return std::move(value_); 100 } else { 101- __builtin_abort(); 102+ PW_ASSERT(false); 103 } 104 } 105 constexpr const T&& value() const&& { 106 if (has_value()) { 107 return std::move(value_); 108 } else { 109- __builtin_abort(); 110+ PW_ASSERT(false); 111 } 112 } 113 114diff --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 115--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h 116+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h 117@@ -55,6 +55,8 @@ 118 // // fit::result with a different "success" vluae type (or 119 // // fit::result<E>). 120 121+#include "pw_assert/assert.h" 122+ 123 namespace fit { 124 125 // Convenience type to indicate failure without elaboration. 126@@ -280,25 +282,25 @@ class LIB_FIT_NODISCARD result<E, T> { 127 if (is_error()) { 128 return storage_.error_or_value.error; 129 } 130- __builtin_abort(); 131+ PW_ASSERT(false); 132 } 133 constexpr const E& error_value() const& { 134 if (is_error()) { 135 return storage_.error_or_value.error; 136 } 137- __builtin_abort(); 138+ PW_ASSERT(false); 139 } 140 constexpr E&& error_value() && { 141 if (is_error()) { 142 return std::move(storage_.error_or_value.error); 143 } 144- __builtin_abort(); 145+ PW_ASSERT(false); 146 } 147 constexpr const E&& error_value() const&& { 148 if (is_error()) { 149 return std::move(storage_.error_or_value.error); 150 } 151- __builtin_abort(); 152+ PW_ASSERT(false); 153 } 154 155 // Moves the underlying error and returns it as an instance of fit::error, simplifying 156@@ -309,7 +311,7 @@ class LIB_FIT_NODISCARD result<E, T> { 157 if (is_error()) { 158 return error<E>(std::move(storage_.error_or_value.error)); 159 } 160- __builtin_abort(); 161+ PW_ASSERT(false); 162 } 163 164 // Accessors for the underlying value. 165@@ -319,25 +321,25 @@ class LIB_FIT_NODISCARD result<E, T> { 166 if (is_ok()) { 167 return storage_.error_or_value.value; 168 } 169- __builtin_abort(); 170+ PW_ASSERT(false); 171 } 172 constexpr const T& value() const& { 173 if (is_ok()) { 174 return storage_.error_or_value.value; 175 } 176- __builtin_abort(); 177+ PW_ASSERT(false); 178 } 179 constexpr T&& value() && { 180 if (is_ok()) { 181 return std::move(storage_.error_or_value.value); 182 } 183- __builtin_abort(); 184+ PW_ASSERT(false); 185 } 186 constexpr const T&& value() const&& { 187 if (is_ok()) { 188 return std::move(storage_.error_or_value.value); 189 } 190- __builtin_abort(); 191+ PW_ASSERT(false); 192 } 193 194 // Moves the underlying value and returns it as an instance of fit::success, simplifying 195@@ -348,7 +350,7 @@ class LIB_FIT_NODISCARD result<E, T> { 196 if (is_ok()) { 197 return success<T>(std::move(storage_.error_or_value.value)); 198 } 199- __builtin_abort(); 200+ PW_ASSERT(false); 201 } 202 203 // Contingent accessors for the underlying value. 204@@ -377,13 +379,13 @@ class LIB_FIT_NODISCARD result<E, T> { 205 if (is_ok()) { 206 return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); 207 } 208- __builtin_abort(); 209+ PW_ASSERT(false); 210 } 211 constexpr decltype(auto) operator->() const { 212 if (is_ok()) { 213 return ::fit::internal::arrow_operator<T>::forward(storage_.error_or_value.value); 214 } 215- __builtin_abort(); 216+ PW_ASSERT(false); 217 } 218 219 // Accessors for the underlying value. This is a syntax sugar for value(). 220@@ -406,7 +408,7 @@ class LIB_FIT_NODISCARD result<E, T> { 221 storage_.error_or_value.error += std::move(error.value_); 222 return *this; 223 } 224- __builtin_abort(); 225+ PW_ASSERT(false); 226 } 227 228 // Maps a result<E, T> to a result<E2, T> by transforming the error through 229@@ -517,25 +519,25 @@ class LIB_FIT_NODISCARD result<E> { 230 if (is_error()) { 231 return storage_.error_or_value.error; 232 } 233- __builtin_abort(); 234+ PW_ASSERT(false); 235 } 236 constexpr const E& error_value() const& { 237 if (is_error()) { 238 return storage_.error_or_value.error; 239 } 240- __builtin_abort(); 241+ PW_ASSERT(false); 242 } 243 constexpr E&& error_value() && { 244 if (is_error()) { 245 return std::move(storage_.error_or_value.error); 246 } 247- __builtin_abort(); 248+ PW_ASSERT(false); 249 } 250 constexpr const E&& error_value() const&& { 251 if (is_error()) { 252 return std::move(storage_.error_or_value.error); 253 } 254- __builtin_abort(); 255+ PW_ASSERT(false); 256 } 257 258 // Moves the underlying error and returns it as an instance of fit::error, simplifying 259@@ -546,7 +548,7 @@ class LIB_FIT_NODISCARD result<E> { 260 if (is_error()) { 261 return error<E>(std::move(storage_.error_or_value.error)); 262 } 263- __builtin_abort(); 264+ PW_ASSERT(false); 265 } 266 267 // Augments the error value of the result with the given value. The operator E::operator+=(F) must 268@@ -560,7 +562,7 @@ class LIB_FIT_NODISCARD result<E> { 269 storage_.error_or_value.error += std::move(error.value_); 270 return *this; 271 } 272- __builtin_abort(); 273+ PW_ASSERT(false); 274 } 275 276 // Maps a result<E, T> to a result<E2, T> by transforming the error through 277