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