xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/bitwise-pointer-cast-cxx20.cpp (revision fb0ef6b66e3c7e91481568c15ed67c047dab84e1)
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*>(&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>(x);   // Well-defined
27 
28   using IntPtr = int*;
29   using FloatPtr = float*;
30   IntPtr x2{};
31   float bad2 = *std::bit_cast<FloatPtr>(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(&py, &px, sizeof(px));
43   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast]
44   std::memcpy(&py, &px, 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(&y, &x, 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*>(addr);
55   std::memcpy(&p, &addr, sizeof(addr));
56 }
57 
58 void pointer2int()
59 {
60   float* p{};
61   auto addr = std::bit_cast<unsigned long long>(p);
62   std::memcpy(&addr, &p, sizeof(p));
63 }
64