1 // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wint-in-bool-context %s
2 // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall %s
3 // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wint-in-bool-context %s
4 // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wall %s
5 
6 #define ONE 1
7 #define TWO 2
8 
9 #define SHIFT(l, r) l << r
10 #define MM a << a
11 #define AF 1 << 7
12 
13 #ifdef __cplusplus
14 typedef bool boolean;
15 #else
16 typedef _Bool boolean;
17 #endif
18 
19 enum num {
20   zero,
21   one,
22   two,
23 };
24 
test(int a,unsigned b,enum num n)25 int test(int a, unsigned b, enum num n) {
26   boolean r;
27   r = a << a;    // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
28   r = MM;        // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
29   r = (1 << 7);  // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
30   r = 2UL << 2;  // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
31   r = 0 << a;    // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
32   r = 0 << 2;    // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
33   r = 1 << 0;    // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
34   r = 1 << 2;    // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
35   r = 1ULL << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
36   r = 2 << b;    // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << b) != 0'?}}
37   r = (unsigned)(2 << b);
38   r = b << 7;
39   r = (1 << a); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
40   r = TWO << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
41   r = a << 7;   // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 7) != 0'?}}
42   r = ONE << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
43   if (TWO << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
44     return a;
45 
46   for (a = 0; 1 << a; a++) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
47     ;
48 
49   if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}}
50     return a;
51 
52   if (n || two)
53     // expected-warning@-1 {{converting the enum constant to a boolean}}
54     return a;
55 
56   if (n == one || two)
57     // expected-warning@-1 {{converting the enum constant to a boolean}}
58     return a;
59 
60   if (r && two)
61     // expected-warning@-1 {{converting the enum constant to a boolean}}
62     return a;
63 
64   if (two && r)
65     // expected-warning@-1 {{converting the enum constant to a boolean}}
66     return a;
67 
68   if (n == one && two)
69     // expected-warning@-1 {{converting the enum constant to a boolean}}
70     return a;
71 
72   // Don't warn in macros.
73   return SHIFT(1, a);
74 }
75