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