1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2 
3 int f() __attribute__((warn_unused_result));
4 
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));
11 
test()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}}
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 
36 struct X {
37  int foo() __attribute__((warn_unused_result));
38 };
39 
bah()40 void bah() {
41   X x, *x2;
42   x.foo(); // expected-warning {{ignoring return value}}
43   x2->foo(); // expected-warning {{ignoring return value}}
44 }
45 
46 namespace warn_unused_CXX11 {
47 class Status;
48 class Foo {
49  public:
50   Status doStuff();
51 };
52 
53 struct [[clang::warn_unused_result]] Status {
54   bool ok() const;
55   Status& operator=(const Status& x);
Updatewarn_unused_CXX11::Status56   inline void Update(const Status& new_status) {
57     if (ok()) {
58       *this = new_status; //no-warning
59     }
60   }
61 };
62 Status DoSomething();
63 Status& DoSomethingElse();
64 Status* DoAnotherThing();
65 Status** DoYetAnotherThing();
lazy()66 void lazy() {
67   Status s = DoSomething();
68   if (!s.ok()) return;
69   Status &rs = DoSomethingElse();
70   if (!rs.ok()) return;
71   Status *ps = DoAnotherThing();
72   if (!ps->ok()) return;
73   Status **pps = DoYetAnotherThing();
74   if (!(*pps)->ok()) return;
75 
76   (void)DoSomething();
77   (void)DoSomethingElse();
78   (void)DoAnotherThing();
79   (void)DoYetAnotherThing();
80 
81   DoSomething(); // expected-warning {{ignoring return value}}
82   DoSomethingElse();
83   DoAnotherThing();
84   DoYetAnotherThing();
85 }
86 
87 template <typename T>
88 class [[clang::warn_unused_result]] StatusOr {
89 };
90 StatusOr<int> doit();
test()91 void test() {
92   Foo f;
93   f.doStuff(); // expected-warning {{ignoring return value}}
94   doit(); // expected-warning {{ignoring return value}}
95 
96   auto func = []() { return Status(); };
97   func(); // expected-warning {{ignoring return value}}
98 }
99 }
100 
101 namespace PR17587 {
102 struct [[clang::warn_unused_result]] Status;
103 
104 struct Foo {
105   Status Bar();
106 };
107 
108 struct Status {};
109 
Bar()110 void Bar() {
111   Foo f;
112   f.Bar(); // expected-warning {{ignoring return value}}
113 };
114 
115 }
116 
117 namespace PR18571 {
118 // Unevaluated contexts should not trigger unused result warnings.
119 template <typename T>
foo(T)120 auto foo(T) -> decltype(f(), bool()) { // Should not warn.
121   return true;
122 }
123 
g()124 void g() {
125   foo(1);
126 }
127 }
128 
129 namespace std {
130 class type_info { };
131 }
132 
133 namespace {
134 // The typeid expression operand is evaluated only when the expression type is
135 // a glvalue of polymorphic class type.
136 
137 struct B {
f__anon759a5d120211::B138   virtual void f() {}
139 };
140 
141 struct D : B {
f__anon759a5d120211::D142   void f() override {}
143 };
144 
145 struct C {};
146 
g()147 void g() {
148   // The typeid expression operand is evaluated only when the expression type is
149   // a glvalue of polymorphic class type; otherwise the expression operand is not
150   // evaluated and should not trigger a diagnostic.
151   D d;
152   C c;
153   (void)typeid(f(), c); // Should not warn.
154   (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'}}
155 
156   // The sizeof expression operand is never evaluated.
157   (void)sizeof(f(), c); // Should not warn.
158 
159    // The noexcept expression operand is never evaluated.
160   (void)noexcept(f(), false); // Should not warn.
161 }
162 }
163