• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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