Clang Project

clang_source_code/test/SemaCXX/warn-unused-result.cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3int f() __attribute__((warn_unused_result));
4
5struct S {
6  void t() const;
7};
8S g1() __attribute__((warn_unused_result));
9S *g2() __attribute__((warn_unused_result));
10S &g3() __attribute__((warn_unused_result));
11
12void test() {
13  f(); // expected-warning {{ignoring return value}}
14  g1(); // expected-warning {{ignoring return value}}
15  g2(); // expected-warning {{ignoring return value}}
16  g3(); // expected-warning {{ignoring return value}}
17
18  (void)f();
19  (void)g1();
20  (void)g2();
21  (void)g3();
22
23  if (f() == 0) return;
24
25  g1().t();
26  g2()->t();
27  g3().t();
28
29  int i = f();
30  S s1 = g1();
31  S *s2 = g2();
32  S &s3 = g3();
33  const S &s4 = g1();
34}
35
36void testSubstmts(int i) {
37  switch (i) {
38  case 0:
39    f(); // expected-warning {{ignoring return value}}
40  default:
41    f(); // expected-warning {{ignoring return value}}
42  }
43
44  if (i)
45    f(); // expected-warning {{ignoring return value}}
46  else
47    f(); // expected-warning {{ignoring return value}}
48
49  while (i)
50    f(); // expected-warning {{ignoring return value}}
51
52  do
53    f(); // expected-warning {{ignoring return value}}
54  while (i);
55
56  for (f(); // expected-warning {{ignoring return value}}
57       ;
58       f() // expected-warning {{ignoring return value}}
59      )
60    f(); // expected-warning {{ignoring return value}}
61
62  f(),  // expected-warning {{ignoring return value}}
63  (void)f();
64}
65
66struct X {
67 int foo() __attribute__((warn_unused_result));
68};
69
70void bah() {
71  X x, *x2;
72  x.foo(); // expected-warning {{ignoring return value}}
73  x2->foo(); // expected-warning {{ignoring return value}}
74}
75
76namespace warn_unused_CXX11 {
77class Status;
78class Foo {
79 public:
80  Status doStuff();
81};
82
83struct [[clang::warn_unused_result]] Status {
84  bool ok() const;
85  Status& operator=(const Status& x);
86  inline void Update(const Status& new_status) {
87    if (ok()) {
88      *this = new_status; //no-warning
89    }
90  }
91};
92Status DoSomething();
93Status& DoSomethingElse();
94Status* DoAnotherThing();
95Status** DoYetAnotherThing();
96void lazy() {
97  Status s = DoSomething();
98  if (!s.ok()) return;
99  Status &rs = DoSomethingElse();
100  if (!rs.ok()) return;
101  Status *ps = DoAnotherThing();
102  if (!ps->ok()) return;
103  Status **pps = DoYetAnotherThing();
104  if (!(*pps)->ok()) return;
105
106  (void)DoSomething();
107  (void)DoSomethingElse();
108  (void)DoAnotherThing();
109  (void)DoYetAnotherThing();
110
111  DoSomething(); // expected-warning {{ignoring return value}}
112  DoSomethingElse();
113  DoAnotherThing();
114  DoYetAnotherThing();
115}
116
117template <typename T>
118class [[clang::warn_unused_result]] StatusOr {
119};
120StatusOr<int> doit();
121void test() {
122  Foo f;
123  f.doStuff(); // expected-warning {{ignoring return value}}
124  doit(); // expected-warning {{ignoring return value}}
125
126  auto func = []() { return Status(); };
127  func(); // expected-warning {{ignoring return value}}
128}
129}
130
131namespace PR17587 {
132struct [[clang::warn_unused_result]] Status;
133
134struct Foo {
135  Status Bar();
136};
137
138struct Status {};
139
140void Bar() {
141  Foo f;
142  f.Bar(); // expected-warning {{ignoring return value}}
143};
144
145}
146
147namespace PR18571 {
148// Unevaluated contexts should not trigger unused result warnings.
149template <typename T>
150auto foo(T) -> decltype(f(), bool()) { // Should not warn.
151  return true;
152}
153
154void g() {
155  foo(1);
156}
157}
158
159namespace std {
160class type_info { };
161}
162
163namespace {
164// The typeid expression operand is evaluated only when the expression type is
165// a glvalue of polymorphic class type.
166
167struct B {
168  virtual void f() {}
169};
170
171struct D : B {
172  void f() override {}
173};
174
175struct C {};
176
177void g() {
178  // The typeid expression operand is evaluated only when the expression type is
179  // a glvalue of polymorphic class type; otherwise the expression operand is not
180  // evaluated and should not trigger a diagnostic.
181  D d;
182  C c;
183  (void)typeid(f(), c); // Should not warn.
184  (void)typeid(f(), d); // expected-warning {{ignoring return value}} expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
185
186  // The sizeof expression operand is never evaluated.
187  (void)sizeof(f(), c); // Should not warn.
188
189   // The noexcept expression operand is never evaluated.
190  (void)noexcept(f(), false); // Should not warn.
191}
192}
193
194namespace {
195// C++ Methods should warn even in their own class.
196struct [[clang::warn_unused_result]] S {
197  S DoThing() { return {}; };
198  S operator++(int) { return {}; };
199  S operator--(int) { return {}; };
200  // Improperly written prefix.
201  S operator++() { return {}; };
202  S operator--() { return {}; };
203};
204
205struct [[clang::warn_unused_result]] P {
206  P DoThing() { return {}; };
207};
208
209P operator++(const P &, int) { return {}; };
210P operator--(const P &, int) { return {}; };
211// Improperly written prefix.
212P operator++(const P &) { return {}; };
213P operator--(const P &) { return {}; };
214
215void f() {
216  S s;
217  P p;
218  s.DoThing(); // expected-warning {{ignoring return value}}
219  p.DoThing(); // expected-warning {{ignoring return value}}
220  // Only postfix is expected to warn when written correctly.
221  s++; // expected-warning {{ignoring return value}}
222  s--; // expected-warning {{ignoring return value}}
223  p++; // expected-warning {{ignoring return value}}
224  p--; // expected-warning {{ignoring return value}}
225  // Improperly written prefix operators should still warn.
226  ++s; // expected-warning {{ignoring return value}}
227  --s; // expected-warning {{ignoring return value}}
228  ++p; // expected-warning {{ignoring return value}}
229  --p; // expected-warning {{ignoring return value}}
230
231  // Silencing the warning by cast to void still works.
232  (void)s.DoThing();
233  (void)s++;
234  (void)p++;
235  (void)++s;
236  (void)++p;
237}
238} // namespace
239
240namespace PR39837 {
241[[clang::warn_unused_result]] int f(int);
242
243void g() {
244  int a[2];
245  for (int b : a)
246    f(b); // expected-warning {{ignoring return value}}
247}
248} // namespace PR39837
249