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