xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/bitwise-pointer-cast-cxx20.cpp (revision fb0ef6b66e3c7e91481568c15ed67c047dab84e1)
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