xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp (revision d25e24a0eb909b7604572d28d15cbe648ecccd90)
1 // RUN: %check_clang_tidy %s bugprone-casting-through-void %t
2 
3 using V = void*;
4 using CV = const void*;
5 
6 int i = 100;
7 double d = 100;
8 const int ci = 100;
9 const double cd = 100;
10 
11 void normal_test() {
12   static_cast<int *>(static_cast<void *>(&d));
13   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
14   static_cast<int *>(static_cast<V>(&d));
15   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'V' (aka 'void *'); use reinterpret_cast instead [bugprone-casting-through-void]
16   static_cast<int *>(static_cast<void *>(&i));
17   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'int *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
18 
19   static_cast<void *>(static_cast<void *>(&i));
20 }
21 
22 void const_pointer_test() {
23   static_cast<int *const>(static_cast<void *>(&d));
24   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
25   static_cast<int *const>(static_cast<V>(&d));
26   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *const' through 'V' (aka 'void *'); use reinterpret_cast instead [bugprone-casting-through-void]
27   static_cast<int *const>(static_cast<void *>(&i));
28   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'int *' to 'int *const' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
29 
30   static_cast<void *const>(static_cast<void *>(&i));
31 }
32 
33 void const_test() {
34   static_cast<const int *>(static_cast<const void *>(&d));
35   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void]
36   static_cast<const int *>(static_cast<const V>(&d));
37   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'double *' to 'const int *' through 'const V' (aka 'void *const'); use reinterpret_cast instead [bugprone-casting-through-void]
38   static_cast<const int *>(static_cast<const void *>(&i));
39   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'int *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void]
40 
41   static_cast<const void *>(static_cast<const void *>(&i));
42 
43   static_cast<const int *>(static_cast<const void *>(&cd));
44   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void]
45   static_cast<const int *>(static_cast<const CV>(&cd));
46   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const double *' to 'const int *' through 'const CV' (aka 'const void *const'); use reinterpret_cast instead [bugprone-casting-through-void]
47   static_cast<const int *>(static_cast<const void *>(&ci));
48   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not cast 'const int *' to 'const int *' through 'const void *'; use reinterpret_cast instead [bugprone-casting-through-void]
49 
50   static_cast<const void *>(static_cast<const void *>(&ci));
51 }
52 
53 
54 void reinterpret_cast_test() {
55   static_cast<int *>(reinterpret_cast<void *>(&d));
56   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
57   reinterpret_cast<int *>(static_cast<void *>(&d));
58   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
59   reinterpret_cast<int *>(reinterpret_cast<void *>(&d));
60   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
61 
62   static_cast<void *>(reinterpret_cast<void *>(&i));
63   reinterpret_cast<void *>(reinterpret_cast<void *>(&i));
64   reinterpret_cast<void *>(static_cast<void *>(&i));
65 }
66 
67 void c_style_cast_test() {
68   static_cast<int *>((void *)&d);
69   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
70   (int *)(void *)&d;
71   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
72   static_cast<int *>((void *)&d);
73   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
74 
75   static_cast<void *>((void *)&i);
76 }
77 
78 struct A {
79    A(void*);
80 };
81 using I = int *;
82 void cxx_functional_cast() {
83   A(static_cast<void*>(&d));
84   I(static_cast<void*>(&d));
85   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not cast 'double *' to 'I' (aka 'int *') through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
86 }
87 
88 void bit_cast() {
89   __builtin_bit_cast(int *, static_cast<void *>(&d));
90   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not cast 'double *' to 'int *' through 'void *'; use reinterpret_cast instead [bugprone-casting-through-void]
91 }
92 
93 namespace PR87069 {
94   void castconstVoidToVoid() {
95     const void* ptr = nullptr;
96     int* numberPtr = static_cast<int*>(const_cast<void*>(ptr));
97   }
98 }
99