xref: /aosp_15_r20/external/clang/test/SemaCXX/warn-bool-conversion.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li namespace BooleanFalse {
4*67e74705SXin Li int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
5*67e74705SXin Li 
foo(int * i,int * j=(false))6*67e74705SXin Li void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
7*67e74705SXin Li {
8*67e74705SXin Li   foo(false); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
9*67e74705SXin Li   foo((int*)false); // no-warning: explicit cast
10*67e74705SXin Li   foo(0); // no-warning: not a bool, even though its convertible to bool
11*67e74705SXin Li 
12*67e74705SXin Li   foo(false == true); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
13*67e74705SXin Li   foo((42 + 24) < 32); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
14*67e74705SXin Li 
15*67e74705SXin Li   const bool kFlag = false;
16*67e74705SXin Li   foo(kFlag); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li char f(struct Undefined*);
20*67e74705SXin Li double f(...);
21*67e74705SXin Li 
22*67e74705SXin Li // Ensure that when using false in metaprogramming machinery its conversion
23*67e74705SXin Li // isn't flagged.
24*67e74705SXin Li template <int N> struct S {};
25*67e74705SXin Li S<sizeof(f(false))> s;
26*67e74705SXin Li 
27*67e74705SXin Li }
28*67e74705SXin Li 
29*67e74705SXin Li namespace Function {
30*67e74705SXin Li void f1();
31*67e74705SXin Li 
32*67e74705SXin Li struct S {
33*67e74705SXin Li   static void f2();
34*67e74705SXin Li };
35*67e74705SXin Li 
36*67e74705SXin Li extern void f3() __attribute__((weak_import));
37*67e74705SXin Li 
38*67e74705SXin Li struct S2 {
39*67e74705SXin Li   static void f4() __attribute__((weak_import));
40*67e74705SXin Li };
41*67e74705SXin Li 
42*67e74705SXin Li bool f5();
43*67e74705SXin Li bool f6(int);
44*67e74705SXin Li 
bar()45*67e74705SXin Li void bar() {
46*67e74705SXin Li   bool b;
47*67e74705SXin Li 
48*67e74705SXin Li   b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
49*67e74705SXin Li              expected-note {{prefix with the address-of operator to silence this warning}}
50*67e74705SXin Li   if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
51*67e74705SXin Li                 expected-note {{prefix with the address-of operator to silence this warning}}
52*67e74705SXin Li   b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
53*67e74705SXin Li                 expected-note {{prefix with the address-of operator to silence this warning}}
54*67e74705SXin Li   if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
55*67e74705SXin Li                    expected-note {{prefix with the address-of operator to silence this warning}}
56*67e74705SXin Li   b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
57*67e74705SXin Li              expected-note {{prefix with the address-of operator to silence this warning}} \
58*67e74705SXin Li              expected-note {{suffix with parentheses to turn this into a function call}}
59*67e74705SXin Li   b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
60*67e74705SXin Li              expected-note {{prefix with the address-of operator to silence this warning}}
61*67e74705SXin Li 
62*67e74705SXin Li   // implicit casts of weakly imported symbols are ok:
63*67e74705SXin Li   b = f3;
64*67e74705SXin Li   if (f3) {}
65*67e74705SXin Li   b = S2::f4;
66*67e74705SXin Li   if (S2::f4) {}
67*67e74705SXin Li }
68*67e74705SXin Li }
69*67e74705SXin Li 
70*67e74705SXin Li namespace Array {
71*67e74705SXin Li   #define GetValue(ptr)  ((ptr) ? ptr[0] : 0)
72*67e74705SXin Li   extern int a[] __attribute__((weak));
73*67e74705SXin Li   int b[] = {8,13,21};
74*67e74705SXin Li   struct {
75*67e74705SXin Li     int x[10];
76*67e74705SXin Li   } c;
77*67e74705SXin Li   const char str[] = "text";
ignore()78*67e74705SXin Li   void ignore() {
79*67e74705SXin Li     if (a) {}
80*67e74705SXin Li     if (a) {}
81*67e74705SXin Li     (void)GetValue(b);
82*67e74705SXin Li   }
test()83*67e74705SXin Li   void test() {
84*67e74705SXin Li     if (b) {}
85*67e74705SXin Li     // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
86*67e74705SXin Li     if (b) {}
87*67e74705SXin Li     // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
88*67e74705SXin Li     if (c.x) {}
89*67e74705SXin Li     // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
90*67e74705SXin Li     if (str) {}
91*67e74705SXin Li     // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
92*67e74705SXin Li   }
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li namespace Pointer {
96*67e74705SXin Li   extern int a __attribute__((weak));
97*67e74705SXin Li   int b;
98*67e74705SXin Li   static int c;
99*67e74705SXin Li   class S {
100*67e74705SXin Li   public:
101*67e74705SXin Li     static int a;
102*67e74705SXin Li     int b;
103*67e74705SXin Li   };
ignored()104*67e74705SXin Li   void ignored() {
105*67e74705SXin Li     if (&a) {}
106*67e74705SXin Li   }
test()107*67e74705SXin Li   void test() {
108*67e74705SXin Li     S s;
109*67e74705SXin Li     if (&b) {}
110*67e74705SXin Li     // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
111*67e74705SXin Li     if (&c) {}
112*67e74705SXin Li     // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
113*67e74705SXin Li     if (&s.a) {}
114*67e74705SXin Li     // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
115*67e74705SXin Li     if (&s.b) {}
116*67e74705SXin Li     // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
117*67e74705SXin Li     if (&S::a) {}
118*67e74705SXin Li     // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
119*67e74705SXin Li   }
120*67e74705SXin Li }
121*67e74705SXin Li 
122*67e74705SXin Li namespace macros {
123*67e74705SXin Li   #define assert(x) if (x) {}
124*67e74705SXin Li   #define zero_on_null(x) ((x) ? *(x) : 0)
125*67e74705SXin Li 
126*67e74705SXin Li   int array[5];
127*67e74705SXin Li   void fun();
128*67e74705SXin Li   int x;
129*67e74705SXin Li 
test()130*67e74705SXin Li   void test() {
131*67e74705SXin Li     assert(array);
132*67e74705SXin Li     assert(array && "expecting null pointer");
133*67e74705SXin Li     // expected-warning@-1{{address of array 'array' will always evaluate to 'true'}}
134*67e74705SXin Li 
135*67e74705SXin Li     assert(fun);
136*67e74705SXin Li     assert(fun && "expecting null pointer");
137*67e74705SXin Li     // expected-warning@-1{{address of function 'fun' will always evaluate to 'true'}}
138*67e74705SXin Li     // expected-note@-2 {{prefix with the address-of operator to silence this warning}}
139*67e74705SXin Li 
140*67e74705SXin Li     // TODO: warn on assert(&x) while not warning on zero_on_null(&x)
141*67e74705SXin Li     zero_on_null(&x);
142*67e74705SXin Li     assert(zero_on_null(&x));
143*67e74705SXin Li     assert(&x);
144*67e74705SXin Li     assert(&x && "expecting null pointer");
145*67e74705SXin Li     // expected-warning@-1{{address of 'x' will always evaluate to 'true'}}
146*67e74705SXin Li   }
147*67e74705SXin Li }
148