1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef PARTITION_ALLOC_POINTERS_RAW_PTR_CAST_H_
6 #define PARTITION_ALLOC_POINTERS_RAW_PTR_CAST_H_
7
8 #include <memory>
9 #include <type_traits>
10
11 // This header is explicitly allowlisted from a clang plugin rule at
12 // "tools/clang/plugins/FindBadRawPtrPatterns.cpp". You can bypass these checks
13 // by performing casts explicitly with functions here.
14 namespace base {
15
16 // Wrapper for |static_cast<T>(src)|.
17 template <typename Dest, typename Source>
unsafe_raw_ptr_static_cast(Source && source)18 inline constexpr Dest unsafe_raw_ptr_static_cast(Source&& source) noexcept {
19 return static_cast<Dest>(source);
20 }
21
22 // Wrapper for |reinterpret_cast<T>(src)|.
23 template <typename Dest, typename Source>
unsafe_raw_ptr_reinterpret_cast(Source && source)24 inline constexpr Dest unsafe_raw_ptr_reinterpret_cast(
25 Source&& source) noexcept {
26 return reinterpret_cast<Dest>(source);
27 }
28
29 // Wrapper for |std::bit_cast<T>(src)|.
30 // Though we have similar implementations at |absl::bit_cast| and
31 // |base::bit_cast|, it is important to perform casting in this file to
32 // correctly exclude from the check.
33 template <typename Dest, typename Source>
unsafe_raw_ptr_bit_cast(const Source & source)34 inline constexpr Dest unsafe_raw_ptr_bit_cast(const Source& source) noexcept {
35 static_assert(!std::is_pointer_v<Source>,
36 "bit_cast must not be used on pointer types");
37 static_assert(!std::is_pointer_v<Dest>,
38 "bit_cast must not be used on pointer types");
39 static_assert(!std::is_reference_v<Source>,
40 "bit_cast must not be used on reference types");
41 static_assert(!std::is_reference_v<Dest>,
42 "bit_cast must not be used on reference types");
43 static_assert(
44 sizeof(Dest) == sizeof(Source),
45 "bit_cast requires source and destination types to be the same size");
46 static_assert(std::is_trivially_copyable_v<Source>,
47 "bit_cast requires the source type to be trivially copyable");
48 static_assert(
49 std::is_trivially_copyable_v<Dest>,
50 "bit_cast requires the destination type to be trivially copyable");
51
52 return __builtin_bit_cast(Dest, source);
53 }
54
55 } // namespace base
56
57 #endif // PARTITION_ALLOC_POINTERS_RAW_PTR_CAST_H_
58