1+ #include < cstdint>
2+
3+ struct TestStruct {
4+ std::int32_t m1;
5+ std::int32_t m2;
6+ };
7+
8+ enum TestEnum { VALUE1, VALUE2 };
9+
10+ void test_integral_to_pointer_cast () {
11+ std::int32_t l1 = 42 ;
12+ std::int64_t l2 = 0x1000 ;
13+
14+ // Casting integral types to pointer types
15+ TestStruct *l4 = reinterpret_cast <TestStruct *>(l1); // NON_COMPLIANT
16+ TestStruct *l5 = reinterpret_cast <TestStruct *>(l2); // NON_COMPLIANT
17+ std::int32_t *l7 = reinterpret_cast <std::int32_t *>(l2); // NON_COMPLIANT
18+ }
19+
20+ void test_enumerated_to_pointer_cast () {
21+ TestEnum l1 = VALUE1;
22+
23+ // Casting enumerated types to pointer types
24+ TestStruct *l3 = reinterpret_cast <TestStruct *>(l1); // NON_COMPLIANT
25+ std::int32_t *l5 = reinterpret_cast <std::int32_t *>(l1); // NON_COMPLIANT
26+ }
27+
28+ void test_void_pointer_to_object_pointer_cast () {
29+ void *l1 = nullptr ;
30+
31+ // Casting void pointer to object pointer types
32+ TestStruct *l2 = static_cast <TestStruct *>(l1); // NON_COMPLIANT
33+ TestStruct *l3 = reinterpret_cast <TestStruct *>(l1); // NON_COMPLIANT
34+ std::int32_t *l4 = static_cast <std::int32_t *>(l1); // NON_COMPLIANT
35+ std::int32_t *l5 = reinterpret_cast <std::int32_t *>(l1); // NON_COMPLIANT
36+ }
37+
38+ void test_integral_to_void_pointer_cast () {
39+ std::int32_t l1 = 42 ;
40+ std::int64_t l2 = 0x1000 ;
41+
42+ // Casting integral types to void pointer
43+ void *l3 = reinterpret_cast <void *>(l1); // NON_COMPLIANT
44+ void *l4 = reinterpret_cast <void *>(l2); // NON_COMPLIANT
45+ }
46+
47+ void test_compliant_void_pointer_casts () {
48+ void *l1 = nullptr ;
49+ const void *l2 = nullptr ;
50+
51+ // Casts between void pointers are allowed
52+ const void *l3 = const_cast <const void *>(l1); // COMPLIANT
53+ void *l4 = const_cast <void *>(l2); // COMPLIANT
54+ volatile void *l5 = static_cast <volatile void *>(l1); // COMPLIANT
55+ }
56+
57+ void f1 () {}
58+ void f2 (int ) {}
59+
60+ void test_compliant_function_pointer_exceptions () {
61+ std::int64_t l1 = 0x1000 ;
62+
63+ // Function pointer casts are exceptions to this rule
64+ void (*l2)() = reinterpret_cast <void (*)()>(l1); // COMPLIANT
65+ void (*l3)(int ) = reinterpret_cast <void (*)(int )>(l1); // COMPLIANT
66+ }
67+
68+ struct TestClass {
69+ void memberFunc ();
70+ std::int32_t m1;
71+ };
72+
73+ void test_compliant_member_function_pointer_exceptions () {
74+ void *l1 = nullptr ;
75+
76+ // Member function pointer casts are technically exceptions to this rule, but
77+ // are prohibited by the compiler.
78+ // void (TestClass::*l2)() =
79+ // reinterpret_cast<void (TestClass::*)()>(l1); // COMPLIANT
80+ }
81+
82+ void test_compliant_regular_pointer_operations () {
83+ TestStruct l1;
84+ TestStruct *l2 = &l1;
85+ std::int32_t *l3 = &l1.m1 ;
86+
87+ // Regular pointer operations that don't involve forbidden casts
88+ TestStruct *l4 = l2; // COMPLIANT
89+ std::int32_t *l5 = l3; // COMPLIANT
90+ }
0 commit comments