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()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 36 struct X { 37 int foo() __attribute__((warn_unused_result)); 38 }; 39 bah()40void 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()66void 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()91void 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()110void 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)120auto foo(T) -> decltype(f(), bool()) { // Should not warn. 121 return true; 122 } 123 g()124void 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()147void 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