1 // RUN: %check_clang_tidy %s bugprone-multi-level-implicit-pointer-conversion %t
2 
3 using OneStar = void*;
4 using OneStarFancy = OneStar;
5 
6 void takeFirstLevelVoidPtr(OneStar message);
7 void takeFirstLevelConstVoidPtr(const OneStarFancy message);
8 void takeFirstLevelConstVoidPtrConst(const void* const message);
9 void takeSecondLevelVoidPtr(void** message);
10 
11 void** getSecondLevelVoidPtr();
12 void* getFirstLevelVoidPtr();
13 int** getSecondLevelIntPtr();
14 int* getFirstLevelIntPtr();
15 
16 int table[5];
17 
test()18 void test()
19 {
20   void** secondLevelVoidPtr;
21   int* firstLevelIntPtr;
22 
23   // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
24   void* a = getSecondLevelVoidPtr();
25 
26   void** b = getSecondLevelVoidPtr();
27   void* c = getFirstLevelVoidPtr();
28 
29   // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: multilevel pointer conversion from 'int **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
30   void* d = getSecondLevelIntPtr();
31 
32   takeFirstLevelVoidPtr(&table);
33 
34   takeFirstLevelVoidPtr(firstLevelIntPtr);
35 
36   takeFirstLevelVoidPtr(getFirstLevelIntPtr());
37 
38   // CHECK-MESSAGES: :[[@LINE+1]]:25: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
39   takeFirstLevelVoidPtr(secondLevelVoidPtr);
40 
41   // CHECK-MESSAGES: :[[@LINE+1]]:30: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
42   takeFirstLevelConstVoidPtr(secondLevelVoidPtr);
43 
44   // CHECK-MESSAGES: :[[@LINE+1]]:35: warning: multilevel pointer conversion from 'void **' to 'const void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
45   takeFirstLevelConstVoidPtrConst(secondLevelVoidPtr);
46 
47   // CHECK-MESSAGES: :[[@LINE+1]]:35: warning: multilevel pointer conversion from 'void ***' to 'const void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
48   takeFirstLevelConstVoidPtrConst(&secondLevelVoidPtr);
49 
50   takeSecondLevelVoidPtr(secondLevelVoidPtr);
51 
52   // CHECK-MESSAGES: :[[@LINE+1]]:25: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
53   takeFirstLevelVoidPtr(getSecondLevelVoidPtr());
54 
55   // CHECK-MESSAGES: :[[@LINE+1]]:30: warning: multilevel pointer conversion from 'void **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
56   takeFirstLevelConstVoidPtr(getSecondLevelVoidPtr());
57 
58   // CHECK-MESSAGES: :[[@LINE+1]]:35: warning: multilevel pointer conversion from 'void **' to 'const void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
59   takeFirstLevelConstVoidPtrConst(getSecondLevelVoidPtr());
60 
61   // CHECK-MESSAGES: :[[@LINE+1]]:25: warning: multilevel pointer conversion from 'int **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
62   takeFirstLevelVoidPtr(getSecondLevelIntPtr());
63 
64   takeSecondLevelVoidPtr(getSecondLevelVoidPtr());
65 }
66 
67 namespace PR93959 {
68   void free(void*);
69 
test()70   void test() {
71     char **p = nullptr;
72     free(p);
73     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: multilevel pointer conversion from 'char **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion]
74     free((void *)p);
75     free(static_cast<void *>(p));
76   }
77 }
78