• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
15 
16 #include "pw_allocator/config.h"
17 #include "pw_assert/assert.h"
18 #include "pw_preprocessor/compiler.h"
19 
20 namespace pw::allocator {
21 
22 /// Configuration that determines which validation checks will performed.
23 ///
24 /// This purely-static type provides both symbols that can be used to
25 /// conditionally exclude unwanted checks, as well as common arithmetic routines
26 /// that can perform overflow checking when configured to do so.
27 ///
28 /// The behavior of this type is determined by the `PW_ALLOCATOR_HARDENING`
29 /// module configuration option.
30 struct Hardening {
31   enum Checks {
32     kBasic = PW_ALLOCATOR_HARDENING_BASIC,
33     kRobust = PW_ALLOCATOR_HARDENING_ROBUST,
34     kDebug = PW_ALLOCATOR_HARDENING_DEBUG,
35   };
36 
37   static constexpr bool kIncludesBasicChecks =
38       PW_ALLOCATOR_HARDENING >= PW_ALLOCATOR_HARDENING_BASIC;
39 
40   static constexpr bool kIncludesRobustChecks =
41       PW_ALLOCATOR_HARDENING >= PW_ALLOCATOR_HARDENING_ROBUST;
42 
43   static constexpr bool kIncludesDebugChecks =
44       PW_ALLOCATOR_HARDENING >= PW_ALLOCATOR_HARDENING_DEBUG;
45 
46   template <typename T, typename U>
IncrementHardening47   static constexpr void Increment(T& value, U increment) {
48     if constexpr (Hardening::kIncludesRobustChecks) {
49       PW_ASSERT(!PW_ADD_OVERFLOW(value, increment, &value));
50     } else {
51       value += increment;
52     }
53   }
54 
55   template <typename T, typename U>
DecrementHardening56   static constexpr void Decrement(T& value, U increment) {
57     if constexpr (Hardening::kIncludesRobustChecks) {
58       PW_ASSERT(!PW_SUB_OVERFLOW(value, increment, &value));
59     } else {
60       value -= increment;
61     }
62   }
63 
64   template <typename T, typename U>
MultiplyHardening65   static constexpr void Multiply(T& value, U increment) {
66     if constexpr (Hardening::kIncludesRobustChecks) {
67       PW_ASSERT(!PW_MUL_OVERFLOW(value, increment, &value));
68     } else {
69       value *= increment;
70     }
71   }
72 };
73 
74 }  // namespace pw::allocator
75