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