1 // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wbool-operation %s
2 // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall %s
3 // RUN: %clang_cc1 -x c -fsyntax-only -Wbitwise-instead-of-logical -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4 // RUN: %clang_cc1 -x c -fsyntax-only -Wbool-operation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
5 // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wbool-operation %s
6 // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wall %s
7 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wbitwise-instead-of-logical -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
8 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wbool-operation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
9 
10 #ifdef __cplusplus
11 typedef bool boolean;
12 #else
13 typedef _Bool boolean;
14 #endif
15 
16 boolean foo(void);
17 boolean bar(void);
18 boolean baz(void) __attribute__((const));
19 void sink(boolean);
20 
21 #define FOO foo()
22 
test(boolean a,boolean b,int * p,volatile int * q,int i)23 void test(boolean a, boolean b, int *p, volatile int *q, int i) {
24   b = a | b;
25   b = foo() | a;
26   b = (p != 0) | (*p == 42);   // FIXME: also warn for a non-volatile pointer dereference
27   b = foo() | (*q == 42);      // expected-warning {{use of bitwise '|' with boolean operands}}
28                                // expected-note@-1 {{cast one or both operands to int to silence this warning}}
29   b = foo() | (int)(*q == 42); // OK, no warning expected
30   b = a | foo();
31   b = (int)a | foo();     // OK, no warning expected
32   b = foo() | bar();      // expected-warning {{use of bitwise '|' with boolean operands}}
33                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
34                           // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:14}:"||"
35   b = foo() | !bar();     // expected-warning {{use of bitwise '|' with boolean operands}}
36                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
37                           // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:14}:"||"
38   b = foo() | (int)bar(); // OK, no warning expected
39   b = a | baz();
40   b = bar() | FOO;        // expected-warning {{use of bitwise '|' with boolean operands}}
41                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
42                           // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:14}:"||"
43   b = foo() | (int)FOO;   // OK, no warning expected
44   b = b | foo();
45   b = bar() | (i > 4);
46   b = (i == 7) | foo();
47 #ifdef __cplusplus
48   b = foo() bitor bar();  // expected-warning {{use of bitwise '|' with boolean operands}}
49                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
50 #endif
51 
52   if (foo() | bar())      // expected-warning {{use of bitwise '|' with boolean operands}}
53                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
54     ;
55 
56   sink(a | b);
57   sink(a | foo());
58   sink(foo() | bar());    // expected-warning {{use of bitwise '|' with boolean operands}}
59                           // expected-note@-1 {{cast one or both operands to int to silence this warning}}
60 
61   int n = i + 10;
62   b = (n | (n - 1));
63 }
64