1// RUN: %check_clang_tidy %s bugprone-casting-through-void %t
2
3using V = void*;
4using CV = const void*;
5
6int i = 100;
7double d = 100;
8const int ci = 100;
9const double cd = 100;
10
11void 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 *' [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 *') [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 *' [bugprone-casting-through-void]
18
19 static_cast<void *>(static_cast<void *>(&i));
20}
21
22void 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 *' [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 *') [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 *' [bugprone-casting-through-void]
29
30 static_cast<void *const>(static_cast<void *>(&i));
31}
32
33void 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 *' [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') [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 *' [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 *' [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') [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 *' [bugprone-casting-through-void]
49
50 static_cast<const void *>(static_cast<const void *>(&ci));
51}
52
53
54void 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 *' [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 *' [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 *' [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
67void 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 *' [bugprone-casting-through-void]
70 (int *)(void *)&d;
71 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not cast 'double *' to 'int *' through 'void *' [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 *' [bugprone-casting-through-void]
74
75 static_cast<void *>((void *)&i);
76}
77
78struct A {
79 A(void*);
80};
81using I = int *;
82void 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 *' [bugprone-casting-through-void]
86}
87
88void 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 *' [bugprone-casting-through-void]
91}
92

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/casting-through-void.cpp