parentheses.cpp revision 8da488dc0bf10d0b6b8861653e8014f0d06fe322
1// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
2
3bool someConditionFunc();
4
5void conditional_op(int x, int y, bool b) {
6  (void)(x + someConditionFunc() ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '+'}} \
7                                           // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
8                                           // expected-note {{place parentheses around the '+' expression to silence this warning}}
9
10  (void)(x - b ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '-'}} \
11                         // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
12                         // expected-note {{place parentheses around the '-' expression to silence this warning}}
13
14  (void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \
15                                // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
16                                // expected-note {{place parentheses around the '*' expression to silence this warning}}
17}
18
19class Stream {
20public:
21  operator int();
22  Stream &operator<<(int);
23  Stream &operator<<(const char*);
24  Stream &operator>>(int);
25  Stream &operator>>(const char*);
26};
27
28void f(Stream& s, bool b) {
29  (void)(s << b ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '<<'}} \
30                                  // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
31                                  // expected-note {{place parentheses around the '<<' expression to silence this warning}}
32}
33
34struct S {
35  operator int() { return 42; }
36  friend S operator+(const S &lhs, bool) { return S(); }
37};
38
39void test(S *s, bool (S::*m_ptr)()) {
40  (void)(*s + true ? "foo" : "bar"); // expected-warning {{operator '?:' has lower precedence than '+'}} \
41                                     // expected-note {{place parentheses around the '?:' expression to evaluate it first}} \
42                                     // expected-note {{place parentheses around the '+' expression to silence this warning}}
43
44  (void)((*s + true) ? "foo" : "bar"); // No warning.
45
46  // Don't crash on unusual member call expressions.
47  (void)((s->*m_ptr)() ? "foo" : "bar");
48}
49
50void test(int a, int b, int c) {
51  (void)(a >> b + c); // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \
52                         expected-note {{place parentheses around the '+' expression to silence this warning}}
53  (void)(a - b << c); // expected-warning {{operator '<<' has lower precedence than '-'; '-' will be evaluated first}} \
54                         expected-note {{place parentheses around the '-' expression to silence this warning}}
55  Stream() << b + c;
56  Stream() >> b + c; // expected-warning {{operator '>>' has lower precedence than '+'; '+' will be evaluated first}} \
57                        expected-note {{place parentheses around the '+' expression to silence this warning}}
58}
59
60namespace PR15628 {
61  struct BlockInputIter {
62    void* operator++(int);
63    void* operator--(int);
64  };
65
66  void test(BlockInputIter i) {
67    (void)(i++ ? true : false); // no-warning
68    (void)(i-- ? true : false); // no-warning
69  }
70}
71