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