[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / clang / test / SemaCXX / warn-unused-result.cpp
blobd0bb4c9317dd217025fdc324cbb74d48c6896cd7
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
3 int f() __attribute__((warn_unused_result));
5 struct S {
6 void t() const;
7 };
8 S g1() __attribute__((warn_unused_result));
9 S *g2() __attribute__((warn_unused_result));
10 S &g3() __attribute__((warn_unused_result));
12 void 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}}
18 (void)f();
19 (void)g1();
20 (void)g2();
21 (void)g3();
23 if (f() == 0) return;
25 g1().t();
26 g2()->t();
27 g3().t();
29 int i = f();
30 S s1 = g1();
31 S *s2 = g2();
32 S &s3 = g3();
33 const S &s4 = g1();
36 void 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}}
44 if (i)
45 f(); // expected-warning {{ignoring return value}}
46 else
47 f(); // expected-warning {{ignoring return value}}
49 while (i)
50 f(); // expected-warning {{ignoring return value}}
53 f(); // expected-warning {{ignoring return value}}
54 while (i);
56 for (f(); // expected-warning {{ignoring return value}}
58 f() // expected-warning {{ignoring return value}}
60 f(); // expected-warning {{ignoring return value}}
62 f(), // expected-warning {{ignoring return value}}
63 (void)f();
66 struct X {
67 int foo() __attribute__((warn_unused_result));
70 void bah() {
71 X x, *x2;
72 x.foo(); // expected-warning {{ignoring return value}}
73 x2->foo(); // expected-warning {{ignoring return value}}
76 namespace warn_unused_CXX11 {
77 class Status;
78 class Foo {
79 public:
80 Status doStuff();
83 struct [[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
92 Status DoSomething();
93 Status& DoSomethingElse();
94 Status* DoAnotherThing();
95 Status** DoYetAnotherThing();
96 void 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;
106 (void)DoSomething();
107 (void)DoSomethingElse();
108 (void)DoAnotherThing();
109 (void)DoYetAnotherThing();
111 DoSomething(); // expected-warning {{ignoring return value}}
112 DoSomethingElse();
113 DoAnotherThing();
114 DoYetAnotherThing();
117 template <typename T>
118 class [[clang::warn_unused_result]] StatusOr {
120 StatusOr<int> doit();
121 void test() {
122 Foo f;
123 f.doStuff(); // expected-warning {{ignoring return value}}
124 doit(); // expected-warning {{ignoring return value}}
126 auto func = []() { return Status(); };
127 func(); // expected-warning {{ignoring return value}}
131 namespace PR17587 {
132 struct [[clang::warn_unused_result]] Status;
134 struct Foo {
135 Status Bar();
138 struct Status {};
140 void Bar() {
141 Foo f;
142 f.Bar(); // expected-warning {{ignoring return value}}
147 namespace PR18571 {
148 // Unevaluated contexts should not trigger unused result warnings.
149 template <typename T>
150 auto foo(T) -> decltype(f(), bool()) { // Should not warn.
151 return true;
154 void g() {
155 foo(1);
159 namespace std {
160 class type_info { };
163 namespace {
164 // The typeid expression operand is evaluated only when the expression type is
165 // a glvalue of polymorphic class type.
167 struct B {
168 virtual void f() {}
171 struct D : B {
172 void f() override {}
175 struct C {};
177 void 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'}}
186 // The sizeof expression operand is never evaluated.
187 (void)sizeof(f(), c); // Should not warn.
189 // The noexcept expression operand is never evaluated.
190 (void)noexcept(f(), false); // Should not warn.
194 namespace {
195 // C++ Methods should warn even in their own class.
196 struct [[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 {}; };
205 struct [[clang::warn_unused_result]] P {
206 P DoThing() { return {}; };
209 P operator++(const P &, int) { return {}; };
210 P operator--(const P &, int) { return {}; };
211 // Improperly written prefix.
212 P operator++(const P &) { return {}; };
213 P operator--(const P &) { return {}; };
215 void 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}}
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;
238 } // namespace
240 namespace PR39837 {
241 [[clang::warn_unused_result]] int f(int);
243 void g() {
244 int a[2];
245 for (int b : a)
246 f(b); // expected-warning {{ignoring return value}}
248 } // namespace PR39837
250 namespace PR45520 {
251 [[nodiscard]] bool (*f)(); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
252 [[clang::warn_unused_result]] bool (*g)();
253 __attribute__((warn_unused_result)) bool (*h)();
255 void i([[nodiscard]] bool (*fp)()); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}