Home | History | Annotate | Download | only in SemaCXX
      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 
     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 
     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);
     56   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();
     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();
     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 
    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>
    120 auto foo(T) -> decltype(f(), bool()) { // Should not warn.
    121   return true;
    122 }
    123 
    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 {
    138   virtual void f() {}
    139 };
    140 
    141 struct D : B {
    142   void f() override {}
    143 };
    144 
    145 struct C {};
    146 
    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