1 // RUN: %check_clang_tidy %s readability-redundant-function-ptr-dereference %t
2 
3 void f(int i);
4 
positive()5 void positive() {
6   void (*p)(int) = f;
7 
8   (**p)(1);
9   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated dereference of function pointer [readability-redundant-function-ptr-dereference]
10   // CHECK-FIXES: (*p)(1);
11   (*****p)(2);
12   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated
13   // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: redundant repeated
14   // CHECK-MESSAGES: :[[@LINE-3]]:6: warning: redundant repeated
15   // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: redundant repeated
16   // CHECK-FIXES: (*p)(2);
17 }
18 
19 template<typename T>
invoke(const T & fn)20 void invoke(const T& fn) {
21   fn(0); // 1
22   (*fn)(0); // 2
23   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: redundant repeated
24   // CHECK-FIXES: fn(0); // 1
25   // CHECK-FIXES: (fn)(0); // 2
26   // FIXME: Remove unnecessary parentheses.
27 }
28 
29 void f1(int);
30 void f2(double);
31 void f3(char);
32 
instantiate()33 void instantiate() {
34   invoke(f1);
35   invoke(f2);
36   invoke(f3);
37   invoke([](unsigned) {});
38 }
39 
negative()40 void negative() {
41   void (*q)(int) = &f;
42 
43   q(1);
44   (*q)(2);
45 }
46