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