1// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s 2// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++98 %s 3// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++11 %s 4 5// PR4806 6namespace test0 { 7 class Box { 8 public: 9 int i; 10 volatile int j; 11 }; 12 13 void doit() { 14 // pointer to volatile has side effect (thus no warning) 15 Box* box = new Box; 16 box->i; // expected-warning {{expression result unused}} 17 box->j; 18#if __cplusplus <= 199711L 19 // expected-warning@-2 {{expression result unused}} 20#endif 21 } 22} 23 24namespace test1 { 25struct Foo { 26 int i; 27 bool operator==(const Foo& rhs) { 28 return i == rhs.i; 29 } 30}; 31 32#define NOP(x) (x) 33void b(Foo f1, Foo f2) { 34 NOP(f1 == f2); // expected-warning {{expression result unused}} 35} 36#undef NOP 37} 38 39namespace test2 { 40 extern "C++" { 41 namespace std { 42 template<typename T> struct basic_string { 43 struct X {}; 44 void method() const { 45 X* x; 46 &x[0]; // expected-warning {{expression result unused}} 47 } 48 }; 49 typedef basic_string<char> string; 50 void func(const std::string& str) { 51 str.method(); // expected-note {{in instantiation of member function}} 52 } 53 } 54 } 55} 56 57namespace test3 { 58struct Used { 59 Used(); 60 Used(int); 61 Used(int, int); 62}; 63struct __attribute__((warn_unused)) Unused { 64 Unused(); 65 Unused(int); 66 Unused(int, int); 67}; 68void f() { 69 Used(); 70 Used(1); 71 Used(1, 1); 72 Unused(); // expected-warning {{expression result unused}} 73 Unused(1); // expected-warning {{expression result unused}} 74 Unused(1, 1); // expected-warning {{expression result unused}} 75} 76} 77 78namespace std { 79 struct type_info {}; 80} 81 82namespace test4 { 83struct Good { Good &f(); }; 84struct Bad { virtual Bad& f(); }; 85 86void f() { 87 int i = 0; 88 (void)typeid(++i); // expected-warning {{expression with side effects has no effect in an unevaluated context}} 89 90 Good g; 91 (void)typeid(g.f()); // Ok; not a polymorphic use of a glvalue. 92 93 // This is a polymorphic use of a glvalue, which results in the typeid being 94 // evaluated instead of unevaluated. 95 Bad b; 96 (void)typeid(b.f()); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} 97 98 // A dereference of a volatile pointer is a side effecting operation, however 99 // since it is idiomatic code, and the alternatives induce higher maintenance 100 // costs, it is allowed. 101 int * volatile x; 102 (void)sizeof(*x); // Ok 103} 104} 105