1// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
2
3void choice(int);
4int choice(bool);
5
6void test() {
7  // Result of ! must be type bool.
8  int i = choice(!1);
9}
10
11// rdar://8018252
12void f0() {
13  extern void f0_1(int*);
14  register int x;
15  f0_1(&x);
16}
17
18namespace test1 {
19  template <class T> void bar(T &x) { T::fail(); }
20  template <class T> void bar(volatile T &x) {}
21
22  void test_ints() {
23    volatile int x;
24    bar(x = 5);
25    bar(x += 5);
26  }
27
28  enum E { E_zero };
29  void test_enums() {
30    volatile E x;
31    bar(x = E_zero);
32    bar(x += E_zero); // expected-error {{incompatible type}}
33  }
34}
35
36int test2(int x) {
37  return x && 4; // expected-warning {{use of logical '&&' with constant operand}} \
38                   // expected-note {{use '&' for a bitwise operation}} \
39                   // expected-note {{remove constant to silence this warning}}
40
41  return x && sizeof(int) == 4;  // no warning, RHS is logical op.
42  return x && true;
43  return x && false;
44  return x || true;
45  return x || false;
46
47  return x && (unsigned)0; // expected-warning {{use of logical '&&' with constant operand}} \
48                   // expected-note {{use '&' for a bitwise operation}} \
49                   // expected-note {{remove constant to silence this warning}}
50
51  return x || (unsigned)1; // expected-warning {{use of logical '||' with constant operand}} \
52                   // expected-note {{use '|' for a bitwise operation}}
53
54  return x || 0; // expected-warning {{use of logical '||' with constant operand}} \
55                   // expected-note {{use '|' for a bitwise operation}}
56  return x || 1; // expected-warning {{use of logical '||' with constant operand}} \
57                   // expected-note {{use '|' for a bitwise operation}}
58  return x || -1; // expected-warning {{use of logical '||' with constant operand}} \
59                   // expected-note {{use '|' for a bitwise operation}}
60  return x || 5; // expected-warning {{use of logical '||' with constant operand}} \
61                   // expected-note {{use '|' for a bitwise operation}}
62  return x && 0; // expected-warning {{use of logical '&&' with constant operand}} \
63                   // expected-note {{use '&' for a bitwise operation}} \
64                   // expected-note {{remove constant to silence this warning}}
65  return x && 1; // expected-warning {{use of logical '&&' with constant operand}} \
66                   // expected-note {{use '&' for a bitwise operation}} \
67                   // expected-note {{remove constant to silence this warning}}
68  return x && -1; // expected-warning {{use of logical '&&' with constant operand}} \
69                   // expected-note {{use '&' for a bitwise operation}} \
70                   // expected-note {{remove constant to silence this warning}}
71  return x && 5; // expected-warning {{use of logical '&&' with constant operand}} \
72                   // expected-note {{use '&' for a bitwise operation}} \
73                   // expected-note {{remove constant to silence this warning}}
74  return x || (0); // expected-warning {{use of logical '||' with constant operand}} \
75                   // expected-note {{use '|' for a bitwise operation}}
76  return x || (1); // expected-warning {{use of logical '||' with constant operand}} \
77                   // expected-note {{use '|' for a bitwise operation}}
78  return x || (-1); // expected-warning {{use of logical '||' with constant operand}} \
79                   // expected-note {{use '|' for a bitwise operation}}
80  return x || (5); // expected-warning {{use of logical '||' with constant operand}} \
81                   // expected-note {{use '|' for a bitwise operation}}
82  return x && (0); // expected-warning {{use of logical '&&' with constant operand}} \
83                   // expected-note {{use '&' for a bitwise operation}} \
84                   // expected-note {{remove constant to silence this warning}}
85  return x && (1); // expected-warning {{use of logical '&&' with constant operand}} \
86                   // expected-note {{use '&' for a bitwise operation}} \
87                   // expected-note {{remove constant to silence this warning}}
88  return x && (-1); // expected-warning {{use of logical '&&' with constant operand}} \
89                   // expected-note {{use '&' for a bitwise operation}} \
90                   // expected-note {{remove constant to silence this warning}}
91  return x && (5); // expected-warning {{use of logical '&&' with constant operand}} \
92                   // expected-note {{use '&' for a bitwise operation}} \
93                   // expected-note {{remove constant to silence this warning}}
94}
95
96template<unsigned int A, unsigned int B> struct S
97{
98  enum {
99    e1 = A && B,
100    e2 = A && 7      // expected-warning {{use of logical '&&' with constant operand}} \
101                     // expected-note {{use '&' for a bitwise operation}} \
102                     // expected-note {{remove constant to silence this warning}}
103  };
104
105  int foo() {
106    int x = A && B;
107    int y = B && 3;  // expected-warning {{use of logical '&&' with constant operand}} \
108                     // expected-note {{use '&' for a bitwise operation}} \
109                     // expected-note {{remove constant to silence this warning}}
110
111    return x + y;
112  }
113};
114
115void test3() {
116  S<5, 8> s1;
117  S<2, 7> s2;
118  (void)s1.foo();
119  (void)s2.foo();
120}
121
122namespace pr16992 {
123  typedef int T;
124  unsigned getsz() {
125    return (sizeof T());
126  }
127}
128
129void test4() {
130  #define X 0
131  #define Y 1
132  bool r1 = X || Y;
133
134  #define Y2 2
135  bool r2 = X || Y2; // expected-warning {{use of logical '||' with constant operand}} \
136                     // expected-note {{use '|' for a bitwise operation}}
137}
138