1 // RUN: %check_clang_tidy %s bugprone-unused-return-value %t \
2 // RUN: -config='{CheckOptions: \
3 // RUN:  [{key: bugprone-unused-return-value.CheckedFunctions, \
4 // RUN:    value: "::fun;::ns::Outer::Inner::memFun;::ns::Type::staticFun;::ns::ClassTemplate::memFun;::ns::ClassTemplate::staticFun"}]}' \
5 // RUN: --
6 
7 namespace std {
8 
9 template <typename T>
10 T *launder(T *);
11 
12 } // namespace std
13 
14 namespace ns {
15 
16 struct Outer {
17   struct Inner {
18     bool memFun();
19   };
20 };
21 
22 using AliasName = Outer;
23 
24 struct Derived : public Outer::Inner {};
25 
26 struct Retval {
27   int *P;
Retvalns::Retval28   Retval() { P = new int; }
~Retvalns::Retval29   ~Retval() { delete P; }
30 };
31 
32 struct Type {
33   Retval memFun();
34   static Retval staticFun();
35 };
36 
37 template <typename T>
38 struct ClassTemplate {
39   Retval memFun();
40   static Retval staticFun();
41 };
42 
43 } // namespace ns
44 
45 int fun();
46 void fun(int);
47 
warning()48 void warning() {
49   fun();
50   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value returned by this function should be used
51   // CHECK-NOTES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
52 
53   (fun());
54   // CHECK-NOTES: [[@LINE-1]]:4: warning: the value {{.*}} should be used
55   // CHECK-NOTES: [[@LINE-2]]:4: note: cast {{.*}} this warning
56 
57   ns::Outer::Inner ObjA1;
58   ObjA1.memFun();
59   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
60   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
61 
62   ns::AliasName::Inner ObjA2;
63   ObjA2.memFun();
64   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
65   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
66 
67   ns::Derived ObjA3;
68   ObjA3.memFun();
69   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
70   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
71 
72   ns::Type::staticFun();
73   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
74   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
75 
76   ns::ClassTemplate<int> ObjA4;
77   ObjA4.memFun();
78   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
79   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
80 
81   ns::ClassTemplate<int>::staticFun();
82   // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
83   // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
84 }
85 
noWarning()86 void noWarning() {
87   auto R1 = fun();
88 
89   ns::Outer::Inner ObjB1;
90   auto R2 = ObjB1.memFun();
91 
92   auto R3 = ns::Type::staticFun();
93 
94   ns::ClassTemplate<int> ObjB2;
95   auto R4 = ObjB2.memFun();
96 
97   auto R5 = ns::ClassTemplate<int>::staticFun();
98 
99   // test calling a void overload of a checked function
100   fun(5);
101 
102   // test discarding return value of functions that are not configured to be checked
103   int I = 1;
104   std::launder(&I);
105 
106   ns::Type ObjB3;
107   ObjB3.memFun();
108 }
109