1 | // RUN: %check_clang_tidy -std=c++20 %s bugprone-bitwise-pointer-cast %t |
2 | |
3 | void memcpy(void* to, void* dst, unsigned long long size) |
4 | { |
5 | // Dummy implementation for the purpose of the test |
6 | } |
7 | |
8 | namespace std |
9 | { |
10 | template <typename To, typename From> |
11 | To bit_cast(From from) |
12 | { |
13 | // Dummy implementation for the purpose of the test |
14 | To to{}; |
15 | return to; |
16 | } |
17 | |
18 | using ::memcpy; |
19 | } |
20 | |
21 | void pointer2pointer() |
22 | { |
23 | int x{}; |
24 | float bad = *std::bit_cast<float*>(from: &x); // UB, but looks safe due to std::bit_cast |
25 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use 'std::bit_cast' to cast between pointers [bugprone-bitwise-pointer-cast] |
26 | float good = std::bit_cast<float>(from: x); // Well-defined |
27 | |
28 | using IntPtr = int*; |
29 | using FloatPtr = float*; |
30 | IntPtr x2{}; |
31 | float bad2 = *std::bit_cast<FloatPtr>(from: x2); |
32 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: do not use 'std::bit_cast' to cast between pointers [bugprone-bitwise-pointer-cast] |
33 | } |
34 | |
35 | void pointer2pointer_memcpy() |
36 | { |
37 | int x{}; |
38 | int* px{}; |
39 | float y{}; |
40 | float* py{}; |
41 | |
42 | memcpy(to: &py, dst: &px, size: sizeof(px)); |
43 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast] |
44 | std::memcpy(to: &py, dst: &px, size: sizeof(px)); |
45 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast] |
46 | |
47 | std::memcpy(to: &y, dst: &x, size: sizeof(x)); |
48 | } |
49 | |
50 | // Pointer-integer conversions are allowed by this check |
51 | void int2pointer() |
52 | { |
53 | unsigned long long addr{}; |
54 | float* p = std::bit_cast<float*>(from: addr); |
55 | std::memcpy(to: &p, dst: &addr, size: sizeof(addr)); |
56 | } |
57 | |
58 | void pointer2int() |
59 | { |
60 | float* p{}; |
61 | auto addr = std::bit_cast<unsigned long long>(from: p); |
62 | std::memcpy(to: &addr, dst: &p, size: sizeof(p)); |
63 | } |
64 | |