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